请您解释一下,为什么以下示例中的integral_constant和constexpr方法导致不同的行为?
#include <iostream>
using namespace std;
struct Logger
{
// template<typename Type>
// using IsRawString =
// std::integral_constant<bool, std::is_same<const char*, Type>::value || std::is_same<char*, Type>::value>;
template<typename Type>
constexpr bool IsRawString()
{
return std::is_same<const char*, Type>::value || std::is_same<char*, Type>::value;
}
template<typename Type, typename Enable = void>
struct Traits
{
static const int Index = 1;
};
template<typename Type>
struct Traits<Type, std::enable_if_t<IsRawString<Type>()>>
{
static const int Index = 2;
};
template<typename Type>
struct Traits<Type, std::enable_if_t<std::is_pointer<Type>::value && !IsRawString<Type>()>>
{
static const int Index = 3;
};
};
int main()
{
cout << Logger::Traits<int>::Index << endl
<< Logger::Traits<char*>::Index << endl
<< Logger::Traits<const char*>::Index << endl
<< Logger::Traits<void*>::Index << endl;
return 0;
}
integral_constant方法https://ideone.com/WQy71r:
1
2
2
3
constexpr方法https://ideone.com/wPiM1m:
1
1
1
1
如果我从全局范围中删除Logger
结构并使用Traits
,则两种方法都会给结构(https://ideone.com/WGVuXE https://ideone.com/OpTbDm)中的integral_constant提供相同的结果。
答案 0 :(得分:0)
这是因为您的IsRawString()
声明为非static
,并且需要调用类对象。
当编译器尝试生成Logger::Traits<char*>::Index
和Logger::Traits<const char*>::Index
时,使用 SFINAE (http://en.cppreference.com/w/cpp/language/sfinae)并使用constexpr函数拒绝错误的变体。仅生成Traits
的{{1}}表单。尝试将template<typename Type, typename Enable = void>
声明为IsRawString()
成员函数