如果我的库的用户尝试使用不合适的类型实例化模板,我试图触发编译时错误。我已经实施了:
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宏吗?有更好的方法吗?
谢谢!
答案 0 :(得分:5)
您可以使用boost::enable_if
以及类型列表。
定义一个类型列表,其中包含您要支持的所有类型,并编写一些元函数,以检查列表中是否存在给定的类型或不,然后将元函数返回的值传递给enable_if
,以启用/禁用该类。
好吧,我为demo编写了一个代码。它虽然没有使用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:实例化'X':
prog.cpp:68:从这里实例化 prog.cpp:56:错误:'X :: unsupported_type_used'具有不完整的类型
prog.cpp:38:错误:'struct compile_time_error'的声明
希望这会对你有所帮助。
现在你可以编写一个名为enable_if_supported
的类模板,它带有两个类型参数:T
和supported_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
答案 1 :(得分:1)
这个怎么样:
#include <string>
template <typename T>
struct good_type;
template <>
struct good_type< std::string > {};
template <>
struct good_type< int > {};
template < typename T >
struct X
{
good_type< T > someVar;
};
int main(int argc, char** argv)
{
X< std::string > x1;
X< int > x2;
X<float> x3;
}
产生:
main.cpp: In instantiation of ‘X<float>’:
main.cpp:22:12: instantiated from here
main.cpp:15:18: error: ‘X<T>::someVar’ has incomplete type
main.cpp:4:8: error: declaration of ‘struct good_type<float>’
答案 2 :(得分:1)
还有一种方法:
#include <string>
template <typename T>
struct good_type;
template <> struct good_type< std::string > {typedef char value;};
template <> struct good_type< int > {typedef char value;};
template < typename T >
struct X
{
typedef typename good_type< T >::value valid;
};
int main(int argc, char** argv)
{
X< std::string > x1;
X< int > x2;
X<float> x3;
}
将产生:
main.cpp: In instantiation of ‘X<float>’:
main.cpp:19:12: instantiated from here
main.cpp:12:42: error: invalid use of incomplete type ‘struct good_type<float>’
main.cpp:4:8: error: declaration of ‘struct good_type<float>’
您可以创建一个宏来定义有效类型:
#define VALID( x ) template <> struct good_type< x > {typedef char value;}
VALID( std::string );
VALID( int );
答案 3 :(得分:0)
BOOST_MPL_ASSERT
会产生更好的消息:http://ideone.com/BR0GJ
prog.cpp: In instantiation of ‘X<float>’:
prog.cpp:24: instantiated from here
prog.cpp:17: error: no matching function for call to
‘assertion_failed(mpl_::failed************ good_type<float>::************)’
prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:22: warning: unused variable ‘x1’
prog.cpp:23: warning: unused variable ‘x2’
prog.cpp:24: warning: unused variable ‘x3’