我在看这个源代码
template<char... digits>
struct conv2bin;
template<char high, char... digits>
struct conv2bin<high, digits...> {
    static_assert(high == '0' || high == '1', "no bin num!");
    static int const value = (high - '0') * (1 << sizeof...(digits)) + 
                             conv2bin<digits...>::value;
};
template<char high>
struct conv2bin<high> {
    static_assert(high == '0' || high == '1', "no bin num!");
    static int const value = (high - '0');
};
template<char... digits>
constexpr int operator "" _b() {
    return conv2bin<digits...>::value;
}
int array[1010_b];我想知道这是否是有效的C++。
template<char high, char... digits>
struct conv2bin<high, digits...> {这是什么?不是专门化的模板专门化吗?
以及为什么struct声明中有代码行,例如
struct conv2bin<high> {
    static_assert(high == '0' || high == '1', "no bin num!");
    static int const value = (high - '0');
};我很困惑..。
发布于 2013-04-15 17:47:53
您的代码展示了三个新的C++11特性:可变模板、用户定义的文字和静态断言。
一般的变量类模板指定零或多个参数,专门的版本分别指定一个或多个参数,准确地指定一个参数。
// digits can be the empty set, so 0 or more arguments
template<char... digits>
struct conv2bin;
// digits can be the empty set, so 1 or more arguments
template<char high, char... digits>
struct conv2bin<high, digits...>
// fully specialized for 1 argument
template<char high>
struct conv2bin<high>各种模板的完整语法有点古怪,维基百科有一篇不错的文章。它对于另一个C++11特性特别有用:各种函数参数的完美转发。
异国情调的int operator "" _b()定义了用户定义的文字,这是一种将自己的单元添加到类型和表达式中的方法。它简单地意味着整数后面跟着_b是用一个特定的“单位”标记的。有关更多细节,请参见此问题。一个实际的好处是避免未来火星着陆器坠毁(在那里SI和帝国单位被混合在他们的着陆软件中,而编译器不能诊断它)。
static_assert完全按照您的想法来做:它静态地断言它的条件,即在static_assert上。当断言失败时,编译将停止。这是尽快检测错误的好方法。
更新
当您有部分重叠的参数范围()时,变量模板的专门化可能非常令人惊讶:零或多个参数版本将只匹配示例中的空列表(万一您已经为它提供了定义)。
#include <iostream>
template<int... Args>
struct Test
{
   enum { value = 0 }; 
};
template<int I, int... Args>
struct Test<I, Args...>
{
   enum { value = 2 };
};
template<int I>
struct Test<I>
{
   enum { value = 1 };
};
int main()
{
   std::cout << Test<>::value << "\n";     // matches zero or more version
   std::cout << Test<0>::value << "\n";    // matches single argument version
   std::cout << Test<0, 0>::value << "\n"; // matches one or more version, not the zero or more one!
}在LiveWorkSpace上输出。
这当然是部分模板专门化的一般规则的一个例子,该规则规定将选择最专门化的版本(一个或多个版本比零或更多,因为后者总是可以在前者可以使用的地方使用,反之亦然)。但是,由于各种模板之间通常并不是“明显的”不同,所以您应该特别注意它们的部分专门化。
发布于 2013-04-15 18:12:26
template<char... digits>
struct conv2bin;这是一个模板转发声明。不必完全定义它,因为如果以不受支持的方式使用它,您将很快捕获错误(编译将失败)。这个特殊的例子不会导致编译失败,因为专门化涵盖了所有可能的情况。
template<char high, char... digits>
struct conv2bin<high, digits...> {
    static_assert(high == '0' || high == '1', "no bin num!");
    static int const value = (high - '0') * (1 << sizeof...(digits)) + 
                             conv2bin<digits...>::value;
};这是一个部分专门化,其中设置了一个模板值。其余的只是转发到模板类型的“较低层级别”。这个模板结构是完全定义的,并且包含一个int成员变量,它的值取决于'high‘值和下一个模板。
template<char high>
struct conv2bin<high> {
    static_assert(high == '0' || high == '1', "no bin num!");
    static int const value = (high - '0');
};同样,部分模板专门化,在模板参数仅包含其列表中的一个参数时定义值。
因此,总的来说,这是一个使用各种模板的模板元编程。
静态断言的存在是为了限制模板变量可以接受的值。
https://stackoverflow.com/questions/16021509
复制相似问题