C++ decltype(自动)在某些情况下与SFINAE一起工作?
我假设C++ decltype(自动)在某些情况下与SFINAE一起工作?,c++,c++17,sfinae,C++,C++17,Sfinae,我假设decltype(auto)在用于尝试和取消返回类型时是一个不兼容的构造。所以,当你本来会得到一个替换错误时,你会得到一个硬错误 但是为什么下面的程序会起作用呢 #包括 #包括 使用std::cout; 使用std::endl; 模板 类标识{ 公众: 使用类型=T; }; 模板 decltype(自动)构造(T&&){ 返回T{}; } 模板 福班{ 公众: 静态void foo(){ 库特 我假设decltype(auto)在用于尝试和取消返回类型时是一个不兼容的构造 它通常是不兼容的
decltype(auto)
在用于尝试和取消返回类型时是一个不兼容的构造。所以,当你本来会得到一个替换错误时,你会得到一个硬错误
但是为什么下面的程序会起作用呢
#包括
#包括
使用std::cout;
使用std::endl;
模板
类标识{
公众:
使用类型=T;
};
模板
decltype(自动)构造(T&&){
返回T{};
}
模板
福班{
公众:
静态void foo(){
库特
我假设decltype(auto)
在用于尝试和取消返回类型时是一个不兼容的构造
它通常是不兼容的,因为它强制实例化函数体。如果函数体中发生替换失败,那么这将是一个硬编译错误-SFINAE在这里不适用
然而,在本例中,在主体中获得替换失败的唯一方法是如果T
不是默认可构造的。但是您调用construct(T{})
,这已经要求T
是默认可构造的-因此失败将首先发生,或者永远不会发生
相反,发生的替换失败是在替换为typename decltype(construct(T{}))::type
的直接上下文中发生的。当我们在将模板参数实例化为Foo
的直接上下文中时,尝试将::type
从int
中移除时,因此SFINAE仍然适用
演示decltype(auto)
在何处中断SFINAE的一个示例是,我们是否将其实现为:
template <typename T>
decltype(auto) construct() {
return T{};
}
template <typename T, typename = std::void_t<>>
class Foo {
public:
static void foo() {
cout << "Nonspecialized foo called" << endl;
}
};
template <typename T>
class Foo<T,
std::void_t<typename decltype(construct<T>())::type>> {
public:
static void foo() {
cout << "Specialized foo called" << endl;
}
};
模板
decltype(自动)构造(){
返回T{};
}
模板
福班{
公众:
静态void foo(){
可以啊,这很有道理!我的理解显然是不完整的。谢谢!为了完整起见,你能指出标准中的相关部分吗?不知何故,我仍然没有在这里得到错误-?@奇怪,因为现在t{}
首先在直接上下文中。
template <typename T>
decltype(auto) construct() {
return T{};
}
template <typename T, typename = std::void_t<>>
class Foo {
public:
static void foo() {
cout << "Nonspecialized foo called" << endl;
}
};
template <typename T>
class Foo<T,
std::void_t<typename decltype(construct<T>())::type>> {
public:
static void foo() {
cout << "Specialized foo called" << endl;
}
};
struct X {
X(int);
};
Foo<X>::foo(); // hard error, failure is in the body of construct()