c++ - integral_constant 与 constexpr

标签 c++ c++11 templates

您能否解释一下,为什么以下示例中的 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,这两种方法都会给出与结构内 integral_constant 相同的结果 ( https://ideone.com/WGVuXE https://ideone.com/OpTbDm )。

最佳答案

发生这种情况是因为您的 IsRawString()声明为非 static并且它需要类对象才能被调用。

当编译器尝试生成 Logger::Traits<char*>::IndexLogger::Traits<const char*>::Index它使用 SFINAE( http://en.cppreference.com/w/cpp/language/sfinae ) 并使用您的 constexpr 函数拒绝错误的变体。第一个Traitstemplate<typename Type, typename Enable = void> 形式只生成。尝试声明 IsRawString()作为static成员函数

关于c++ - integral_constant 与 constexpr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46650743/

相关文章:

c++ - 创建后无法更改 ListView 中的列宽

C++ 结构 : more members, 成员访问时间慢得多?

C++ 可变参数模板数组/访问元素

css - 如何更改 CSS 模板中的列顺序以将重要内容放在前面?

c++ - 部分模板类型推导

c++ - 类模板中的隐藏好友模板

c++ - 给 Label C++ 的首字母加下划线(下划线不显示)

c++ - 基于低通/高通滤波器掩模 OpenCV 的带阻滤波器掩模

c++ - 不调用放置释放函数

c++ - 为全局 constexpr 变量生成唯一值