文字运算符的模板参数列表

陳 力*_*陳 力 4 c++ language-lawyer template-meta-programming user-defined-literals variadic-templates

这是我将二进制文字转换为十进制的实现:

template<char Head, char... Tail>
constexpr int operator"" _b()
{
    if constexpr (sizeof... (Tail) == 0)
    {
        return Head - '0';
    }
    else
    {
        return (Head - '0') * (1 << sizeof...(Tail)) + operator"" _b<Tail...>();
    }
}
Run Code Online (Sandbox Code Playgroud)

GCC 编译愉快

虽然Clang 失败了

prog.cc:1:2: error: template parameter list for literal operator must be either 'char...' or 'typename T, T...'
        template<char Head, char... Tail>
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:19:27: error: no matching literal operator for call to 'operator""_b' with argument of type 'unsigned long long' or 'const char *', and no matching literal operator template
    std::cout << 110110110_b;
                      ^
Run Code Online (Sandbox Code Playgroud)

icc 也失败了

error: a literal operator template must have a template parameter list equivalent to "<char ...>"

    constexpr int operator"" _b()

                  ^
Run Code Online (Sandbox Code Playgroud)

MSVC 也失败:

<source>(2): error C3686: 'operator ""_b': literal operator template must have exactly one template parameter that is a parameter pack
Run Code Online (Sandbox Code Playgroud)

所以,icc 需要,char...而 clang 和 msvc 需要typename T, T...or char...,只有 gcc 允许 myHeadTail.

解决方法应该是简单----只需更换char Head, char... Tailchar... digits和返回一个新的aux,其使用功能,char Head, char... Tail作为模板参数,或使用那么结构专业headhead, tail...没有if constexpr

但是我在标准草案中没有找到相关要求。你能告诉我哪一个符合标准吗?当然,如果你有更优雅的解决方案(除了我上面提到的两个)不会调用编译器错误,请粘贴在这里,我会非常感激。

Nic*_*las 5

该标准在[over.literal]/5 中非常明确地说明了这一点:

文字运算符模板的声明应具有空参数声明子句,其模板参数列表应具有单个模板参数,该模板参数是具有元素类型的非类型模板参数包char

所以 GCC 允许这样做是错误的。