当模板化类不包含可用的成员函数时,如何在编译时验证模板参数?

sha*_*oth 6 c++ templates metaprogramming visual-c++

我有以下模板struct:

template<int Degree>
struct CPowerOfTen {
enum { Value = 10 * CPowerOfTen<Degree - 1>::Value };
};

template<>
struct CPowerOfTen<0> {
    enum { Value = 1 };
};
Run Code Online (Sandbox Code Playgroud)

这将是这样使用的:

const int NumberOfDecimalDigits = 5;
const int MaxRepresentableValue = CPowerOfTen<NumberOfDecimalDigits>::Value - 1;
// now can use both constants safely - they're surely in sync
Run Code Online (Sandbox Code Playgroud)

现在该模板需要Degree非负面的.我想为此强制执行编译时断言.

我怎么做?我试图添加一个析构函数CPowerOfTen:

~CPowerOfTen() {
    compileTimeAssert( Degree >= 0 );
 }
Run Code Online (Sandbox Code Playgroud)

但由于它没有被直接调用,因此Visual C++ 9决定不实例化它,因此根本不评估编译时断言语句.

我怎么能强制执行编译时检查Degree非负面?

Ale*_*tov 8

template<bool> struct StaticCheck;
template<> struct StaticCheck<true> {};

template<int Degree> 
struct CPowerOfTen : StaticCheck<(Degree > 0)> { 
    enum { Value = 10 * CPowerOfTen<Degree - 1>::Value }; 
}; 

template<> 
struct CPowerOfTen<0> { 
    enum { Value = 1 }; 
}; 
Run Code Online (Sandbox Code Playgroud)

编辑:没有无限递归.

// Help struct
template<bool, int> struct CPowerOfTenHelp;

// positive case    
template<int Degree> 
struct CPowerOfTenHelp<true, Degree> { 
    enum { Value = 10 * CPowerOfTenHelp<true, Degree - 1>::Value }; 
}; 

template<> 
struct CPowerOfTenHelp<true, 0> { 
    enum { Value = 1 }; 
}; 

// negative case
template<int Degree> 
struct CPowerOfTenHelp<false, Degree> {}

// Main struct
template<int Degree> 
struct CPowerOfTen : CPowerOfTenHelp<(Degree >= 0), Degree> {};
Run Code Online (Sandbox Code Playgroud)


Dan*_*Dan 5

你可以使用uint.您不会收到编译时错误,但至少它会自我记录.


Dav*_*eas 5

您可以使用BOOST_STATIC_ASSERT宏.或者实现自己的,最简单的强制失败的方法是执行N个元素数组的typedef,其中N是正/负,具体取决于参数.

该方法的问题在于它会产生故障,但仍将尝试执行递归.boost::enable_if_c如果参数为负,请查看使用SFINAE无法实例化模板.