c++ - 限制模板实例化中的参数类型

标签 c++ templates boost

如果我的库的用户尝试使用不合适的类型实例化模板,我将尝试触发编译时错误。我已经实现:

template <typename T>
struct good_type { enum { value = false }; };

template <>
struct good_type<string> { enum { value = true }; };

template <>
struct good_type<int64_t> { enum { value = true }; };

template <typename T>
struct X
{
  BOOST_STATIC_ASSERT(good_type<T>::value);
};

int main(int argc, char** argv)
{
  X<string> x1; 
  X<int64_t> x2;
  X<float> x3; 
  return 0;
}

这有效,但我从 gcc 得到的消息有点令人惊讶:

error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>' 

我应该使用不同的 Boost 宏吗?有更好的方法吗?

谢谢!

最佳答案

您可以使用 boost::enable_if ,以及类型列表。

定义一个类型列表,其中包含您要支持的所有类型,并编写一些元函数,以检查给定的类型是否存在于列表中或not,然后将元函数返回的值传递给enable_if , 以启用/禁用该类。


好吧,我写了一个演示代码。它没有使用 boost::enable_if虽然(这是供您试验的)。

首先是框架:

////////////////////////////////////////////////////////////
//framework

struct null_type {};

template<typename H, typename  T=null_type>
struct typelist
{
   typedef H Head;
   typedef T Tail;
};

template<typename T, typename TList> struct exists;

template<typename T, typename Tail> 
struct exists<T, typelist<T, Tail> >
{
    static const bool value = true;
};

template<typename T, typename Head, typename Tail> 
struct exists<T, typelist<Head, Tail> >
{
    static const bool value = false || exists<T, Tail>::value;
};

template<typename T> 
struct exists<T, null_type >
{
    static const bool value = false;
};

template<bool>
struct compile_time_error;

template<>
struct compile_time_error<true> {};

--

下面是测试代码:

//////////////////////////////////////////////////////////////
//usage

typedef typelist<int> t1;
typedef typelist<short, t1> t2;
typedef typelist<char, t2> t3;
typedef typelist<unsigned char, t3> t4;

typedef t4 supported_types;//supported_types: int, short, char, unsigned char

template<typename T>
struct X
{
    compile_time_error<exists<T,supported_types>::value> unsupported_type_used;
};

int main() {

 //testing if exists<> work or not!
 cout <<(exists<int,supported_types>::value)<< endl;        //should print 1
 cout <<(exists<unsigned int,supported_types>::value)<<endl;//should print 0
 cout <<(exists<char,supported_types>::value)<< endl;       //should print 1
 cout <<(exists<long,supported_types>::value)<< endl;       //should print 0

 X<int> x1;   //okay - int is supported!
 //X<long> x2;  //error - long is unsupported! 
 return 0;
}

它编译得很好(ideone),并给出这个输出(对于 cout 语句):

1
0
1
0

但是如果你取消注释行 X<long> x2;在上面的代码中,它不会编译,因为 long是不受支持的类型。它给出了这个易于阅读和理解的错误(ideone):

prog.cpp: In instantiation of ‘X’:
prog.cpp:68: instantiated from here
prog.cpp:56: error: ‘X::unsupported_type_used’ has incomplete type
prog.cpp:38: error: declaration of ‘struct compile_time_error’

希望对你有帮助。


现在你可以编写一个名为enable_if_supported 的类模板它有两个类型参数:Tsupported_types .您可以从 enable_if_supported 派生您的类作为:

template<typename T>
struct X : enable_if_supported<T, supported_types>
{
   //your code
};

这看起来有点干净。 enable_if_supported类模板现在在框架部分定义。在这里看到它工作:http://www.ideone.com/EuOgc

关于c++ - 限制模板实例化中的参数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6375634/

相关文章:

c++ - 尽管存在符号链接(symbolic link),ld 仍无法加载库

c++ - 基于范围的循环的 BOOST_FOREACH 和 c++11 之间的区别?

c++ - 使用 boost python 和 python 3.2 的 Hello world

c++ - 在STL算法中调用多个函数

c++ - 运算符重载 - 不匹配

c++ - 直接访问指针是否比通过结构访问指针更快?

c++ - 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str':非标准语法;使用 '&' 创建指向成员的指针

javascript - 在模板的上下文中从另一个助手调用一个助手(Meteor 0.9.4)

c++ - 模板继承(在子类成员函数中访问父类的变量和对象)

c++ - 推导独立函数的返回类型