C ++构造函数SFINAE(C++ constructor SFINAE)

编程入门 行业动态 更新时间:2024-10-12 05:46:09
C ++构造函数SFINAE(C++ constructor SFINAE) #include <iostream> using namespace std; template <typename T> class test { public: T value; template <typename... Args, typename = decltype(T())> test(Args... args): value(args...) { cout <<"ctor running\n"; } template <typename... Args> test(Args...) : value(1) { cout <<"ctor unspec running\n"; } }; class t { public: t() = delete; explicit t(int) {} }; int main() { test<t> h; }

我试图为创建的对象调用第二个constructor ( h )。 我不知道为什么会收到此错误:

prog.cc: In function 'int main()': prog.cc:45:13: error: call of overloaded 'test()' is ambiguous test<t> h; ^ prog.cc:25:5: note: candidate: 'test<T>::test(Args ...) [with Args = {}; T = t]' test(Args... args) ^~~~ prog.cc:19:5: note: candidate: 'test<T>::test(Args ...) [with Args = {}; <template-parameter-2-2> = t; T = t]' test(Args... args): value(args...) ^~~~

我试图让整个class t private但也没有解决它。 我想要第二个constructor运行即打印`

“ctor unspec running”

我在这里想念的是什么? 第一个constructor调用应该是SFINAed ,因为typename = decltype(T())不会工作,因为t不能default constructed ,而是我得到一个ambiguous调用错误。

#include <iostream> using namespace std; template <typename T> class test { public: T value; template <typename... Args, typename = decltype(T())> test(Args... args): value(args...) { cout <<"ctor running\n"; } template <typename... Args> test(Args...) : value(1) { cout <<"ctor unspec running\n"; } }; class t { public: t() = delete; explicit t(int) {} }; int main() { test<t> h; }

I am trying to call the second constructor for the object created (h). I do not know why I get this error:

prog.cc: In function 'int main()': prog.cc:45:13: error: call of overloaded 'test()' is ambiguous test<t> h; ^ prog.cc:25:5: note: candidate: 'test<T>::test(Args ...) [with Args = {}; T = t]' test(Args... args) ^~~~ prog.cc:19:5: note: candidate: 'test<T>::test(Args ...) [with Args = {}; <template-parameter-2-2> = t; T = t]' test(Args... args): value(args...) ^~~~

I tried to make the entire class t private but that did not fix it either. I want the second constructor to run i.e. print `

"ctor unspec running"

What am I missing here? The first constructor call should be SFINAed away since typename = decltype(T()) wont work as t can not be default constructed but instead I get an ambiguous call error.

最满意答案

SFINAE只发生在紧急情况下。 由于T是类的模板参数而不是函数的模板参数,因此它不是直接上下文。 这意味着它成为一个“硬”错误。 这是一个很难的错误,因为不管你发送给constuctor的模板参数的是什么参数,它总是会出错。

一个解决方案是添加一个等于T的模板参数,并用它来制作SFINAE:

template <typename... Args, typename U = T, typename = decltype(U{})> test(Args... args): value(args...) { cout <<"ctor running\n"; }

由于U是直接上下文,因此在此处应用SFINAE。

使用SFINAE,没有订购。 每个匹配函数都是“相等”,这意味着如果有多个匹配函数,则没有“更好”的函数,因为它是受约束的。 所以用相反的约束来限制另一个是一个好主意:

template <typename... Args, typename U = T, std::enable_if_t<!std::is_default_constructible<U>::value>* = nullptr> test(Args...) : value(1) { cout <<"ctor unspec running\n"; }

实例

SFINAE only happen with immediate context. Since T is a template argument of the class and not the template argument of the function, it is not immediate context. That means it becomes an "hard" error. It's an hard error because no matter what argument you send to the template argument of the constuctor, it will always be an error.

A solution would be to add a template argument equal to T, and use it to make SFINAE:

template <typename... Args, typename U = T, typename = decltype(U{})> test(Args... args): value(args...) { cout <<"ctor running\n"; }

Since U is immediate context, SFINAE is applied here.

With SFINAE, there is no ordering done. Every matching function is "equal", which means that if there is multiple matching function, there is no "better" one because it is constrained. So it would be a good idea to constrain the other one with a contrary constraint:

template <typename... Args, typename U = T, std::enable_if_t<!std::is_default_constructible<U>::value>* = nullptr> test(Args...) : value(1) { cout <<"ctor unspec running\n"; }

Live example

更多推荐

本文发布于:2023-08-07 00:02:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1456361.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   SFINAE   constructor

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!