限制模板实例参数类型 [英] Restrict parameter type in template instantiation

查看:148
本文介绍了限制模板实例参数类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想如果我的库的用户尝试实例化一个模板,一个类型,是不恰当的触发编译时错误。我实现了:

I'm trying to trigger a compile time error if the user of my library tries to instantiate a template with a type that is not appropriate. I've implemented:

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

这工作,但我从海湾合作委员会得到的消息是有点出人意料:

which works, but the message I get from gcc is a bit surprising:

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

我应该使用不同的升压宏?有没有更好的方式来做到这一点?

Should I be using a different Boost macro? Is there a better way to do this?

谢谢!

推荐答案

您可以使用的 的boost :: enable_if ,用类型串一起。

You can use boost::enable_if, along with typelist.

定义包含了所有的要支持类型的一个类型,并写一些元函数(S),以检查是否给定的键入的存在于列表或不,再通过其元函数返回 enable_if 的价值,这样才能启用/禁用类。

Define a typelist which contains all the types which you want to support, and write some metafunction(s), to check if a given type exists in the list or not, and then pass the value which metafunction returns to enable_if, so as to enable/disable the class.

好吧,我写了一个code的演示。它不使用的boost :: enable_if 虽然(这是你与实验)。

Alright, I wrote a code for demo. Its not using boost::enable_if though (that is for you to experiment with).

下面是框架第一:

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

-

现在遵循的测试code:

Now follows the testing code:

//////////////////////////////////////////////////////////////
//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 语句):

which compiles perfectly fine (ideone), and gives this output (for the cout statements):

1
0
1
0

但如果你去掉注释 X'LT;长&GT; X2; 在上面的code,它不会编译,因为是不支持的类型。它给这个错误,这是很容易阅读和理解( ideone ):

But if you uncomment the line X<long> x2; in the above code, it will not compile, since long is an unsupported type. And it gives this error, which is easy to read and understand (ideone):

prog.cpp:在'X'实例:结果
  prog.cpp:68:从这里搜索实例
  prog.cpp:56:错误:'X :: unsupported_type_used具有不完整的类型结果
  prog.cpp:38:错误:'结构compile_time_error

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 称为类模板,有两个类型参数: T SUPPORTED_TYPES 。您可以从 enable_if_supported 作为派生类:

Now you can write a class template called enable_if_supported which takes two type arguments: T and supported_types. You can derive your class from enable_if_supported as:

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

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

This looks a bit clean. enable_if_supported class template now is defined in the framework section. See it here working : http://www.ideone.com/EuOgc

这篇关于限制模板实例参数类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆