变异模板的特殊化

Ver*_*tas 1 c++ templates static-assert template-specialization variadic-templates

所以我尝试使用自定义文字运算符来实现二进制文字.但是,似乎我在模板专业化方面做错了.static_assert是在不应该:

template <char... bits>
struct bin_imp
{
        static constexpr unsigned long long to_ull()
        {
                static_assert(false,"not binary value");
                return 0;
        }
};

template <char... bits>
struct bin_imp<'0', bits...>
{
        static constexpr unsigned long long to_ull()
        {
                return bin_imp<bits...>::to_ull();
        }
};

template <char... bits>
struct bin_imp<'1', bits...>
{
        static constexpr unsigned long long to_ull()
        {
                return (1ULL << sizeof...(bits)) | bin_imp<bits...>::to_ull();
        }
};


template <>
struct bin_imp<>
{
        static constexpr unsigned long long to_ull()
        {
                return 0;
        }
};

template <char... bits>
static constexpr unsigned long long operator "" _b ()
{
        return bin_imp<bits...>::to_ull();
};

int main(int argc, char* argv[])
{
        unsigned int i = 11_b;
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Naw*_*waz 5

static_assert(false,"not binary value");
Run Code Online (Sandbox Code Playgroud)

编译器拒绝这一点,因为即使在解析源代码的第一阶段,编译器也很明显它会失败.编译器不需要实例化类模板,以便知道static_assert它将失败.

你可以做的是,强制编译器在解析的第二阶段评估条件 - 即实例化(类模板的)函数.为此,您需要一个类模板,例如:

 template<char ...>
 struct always_false : std::false_type {};
Run Code Online (Sandbox Code Playgroud)

现在用它作为:

static_assert(always_false<bits...>::value,"not binary value");
Run Code Online (Sandbox Code Playgroud)

现在,编译器无法在实例化之前评估条件,always_false<>而该条件恰好始终为false.

也就是说,解决方案是:在评估表达式时变得懒惰.