2017-10-16 121 views
0
#include <iostream> 
#include <functional> 
#include <memory> 

using namespace std; 

template<typename T = int> std::enable_if_t<!std::is_arithmetic<T>{}, T> nope() {} 

int main() { 
    nope(); 
} 

这是一个简单的代码,不会编译。如果一个人改变了这一点:enable_if如何在这种情况下工作

int main() { 
     nope(); 
} 

int main() { 
     nope<std::string>(); 
} 

它开始编译。 问题是为什么这个工作像它的工作?更具体地讲,为什么编译器告诉我:

呼叫到 '没了()'

,而不是像

enable_if没有匹配功能::类型未找到 (这是真的,因为如果条件不满足,它确实不存在)?

谢谢。

+0

既然你问为什么编译偏好另一个错误信息,你应该用你正在使用的编译器标记这个问题。 –

+0

你看到的是[SFINAE](http://en.cppreference.com/w/cpp/language/sfinae)。 – HolyBlackCat

+0

GCC和Clang都给出了体面的错误消息。 Clang甚至给出了注释:候选模板被忽略:被'enable_if'[with T = int]禁用,使用enable_if_t = typename enable_if <_Cond, _Tp> :: type;' – NathanOliver

回答

0

如果您致电nope(),您的template类型默认为intstd::enable_if_t<!std::is_arithmetic<T>{}, T>返回false!std::is_arithmetic<int>{}并失败。

nope<int>()的调用也会失败,原因与为什么nope()失败相同。

另一方面,nope<std::string>得到trueis_arithmetic并返回一个工作函数。

被触发5.0 clang++版本的编译器错误解释的结果很清楚:

候选模板忽略:要求“!std::is_arithmetic<int>{}”不满意[with T = int] std::enable_if_t<!std::is_arithmetic<T>{}, T> nope() {}

+0

是的,我明白了。但据我了解std :: enable_if_t <!std :: is_arithmetic {},T>不会返回false,因为它的定义如下: template using enable_if_t = typename enable_if : :类型; 它应该不会引发编译器错误,因为类型未在B情况下定义==假? – s0nicYouth

+0

它会引发编译器错误,请参阅上面的@ nwp的注释。我的海湾合作委员会也不太清楚,但铿锵的信息是清楚的。 – Chiel

相关问题