简体   繁体   English

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

[英]How do I validate template parameters in compile time when a templated class contains no usable member functions?

I have a following templated struct : 我有一个以下模板化的struct

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

template<>
struct CPowerOfTen<0> {
    enum { Value = 1 };
};

which is to be used like this: 这将是这样使用的:

const int NumberOfDecimalDigits = 5;
const int MaxRepresentableValue = CPowerOfTen<NumberOfDecimalDigits>::Value - 1;
// now can use both constants safely - they're surely in sync

now that template requires Degree to be non-negative. 现在该模板要求Degree为非负数。 I'd like to enforce a compile-time assert for that. 我想为此强制执行编译时断言。

How do I do that? 我怎么做? I tried to add a destructor to CPowerOfTen : 我试图向CPowerOfTen添加一个析构CPowerOfTen

~CPowerOfTen() {
    compileTimeAssert( Degree >= 0 );
 }

but since it is not called directly Visual C++ 9 decides not to instantiate it and so the compile-time assert statement is not evaluated at all. 但由于它没有被直接调用,因此Visual C ++ 9决定不实例化它,因此根本不评估编译时断言语句。

How could I enforce a compile-time check for Degree being non-negative? 如何对Degree为非负的强制执行编译时检查?

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 }; 
}; 

Edit: without infinite recursion. 编辑:没有无限递归。

// 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> {};

You can use a uint. 你可以使用uint。 You won't get a compile time error but at least it will be self-documenting. 您不会收到编译时错误,但至少它会自我记录。

You can use BOOST_STATIC_ASSERT macro. 您可以使用BOOST_STATIC_ASSERT宏。 Or implement your own, the simplest way of forcing a failure is performing a typedef of an array of N elements, where N is positive/negative depending on the argument. 或者实现自己的,最简单的强制失败的方法是执行N个元素数组的typedef,其中N是正/负,具体取决于参数。

The problem with that approach is that it will produce a failure, but will try to perform the recursion nonetheless. 该方法的问题在于它会产生故障,但仍将尝试执行递归。 Take a look at boost::enable_if_c to use SFINAE to fail instantiating the template if the argument is negative. 如果参数为负,请查看boost::enable_if_c以使用SFINAE无法实例化模板。

You can forward the implementation to a class also accepting a bool parameter indicating whether the result can be calculated. 您可以将实现转发给同时接受bool参数的类,该参数指示是否可以计算结果。

#include <limits>
template <int Degree, bool InRange>
struct PowerOfTenImpl
{
    enum {Value = 10 * PowerOfTenImpl<Degree - 1, InRange>::Value};
};

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

template <int Degree>
struct PowerOfTenImpl<Degree, false>
{
};

template<int Degree>
struct CPowerOfTen {
    enum { Value = PowerOfTenImpl<Degree, Degree >= 0 && 
      Degree <= std::numeric_limits<int>::digits10>::Value };
};

int main()
{
    const int a = CPowerOfTen<4>::Value;
    const int b = CPowerOfTen<1000>::Value;
    const int c = CPowerOfTen<-4>::Value;
}

How about implementing a STATIC_CHECK macro? 如何实现STATIC_CHECK宏?

template<bool> struct CompileTimeError;
template<> struct CompileTimeError<true> {}; //specialized only for true

#define STATIC_CHECK(expr)  (CompileTimeError<(expr) != 0>())

Inside main() 里面main()

 const int NumberOfDecimalDigits = -1;
 STATIC_CHECK(NumberOfDecimalDigits > 0); // Error : invalid use of incomplete type struct CompileTimeError<false>

 const int MaxRepresentableValue = CPowerOfTen<NumberOfDecimalDigits>::Value - 1; 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何为模板化类的成员函数定义静态数组? - How do I define a static array to member functions of a templated class? 如何在模板化类型上专门化模板类的静态成员? - How do I specialize a static member of a template class on a templated type? 如何编写带有模板化函数参数的包装函数,该函数可以采用重载成员函数? - How do I write a wrapper function with templated function parameters which can take overloaded member functions? 使用模板化成员函数显式实例化模板类 - Explicit instantiation of template class with templated member functions 如何基于模板化类的基类专门化成员函数 - How do I specialize member functions based on the base class of the templated class 如何在编译时访问模板化类的模板类型? - How to access a template type of a templated class at compile time? 如何在不知道该类是否为模板的情况下调用模板化的成员函数? - How do I call a templated member function without knowing whether or not the class is a template? 什么时候实例化模板类的成员函数? - When are member functions of a templated class instantiated? 当模板参数为特定模板化 class 时使用概念启用成员函数 - Using concepts to enable member functions when the template parameter is a specific templated class 编译模板化类时,在复制构造函数上收到“类中未声明成员函数”错误 - I get “no member function declared in class” error on my copy constructor when I compile a templated class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM