可以编写一个模板,该模板被设计为由用户明确专门化,在默认模板上添加一些有用的错误消息:
template<typename T>
struct foo
{
static_assert( sizeof(T) != sizeof(T) , "Please specialize foo for your type" );
};
由于always-false条件取决于模板参数,因此对该断言的评估将仅在模板即时期间完成,正是我们想要的。
现在考虑相反的情况:我们允许用户使用模板的通用版本,但不允许他使用特定的即时消息。例如:
template<typename T>
struct bar
{
/* something useful for the user */
};
template<>
struct bar<char>
{
static_assert( false , "No, you can't instantiate bar with char" );
};
当然这不起作用,因为断言不依赖于模板参数,即使用户没有实例化bar<char>
,编译也会失败。
我的问题是:在模板即时化之前,有没有办法推迟对那种断言表达式的评估?
编辑:一个更复杂的例子:
template<typename T>
struct quux
{
/* something useful for the user */
};
/* This specialization is defined to reject any instance of quux which uses a
* template with bool as parameter
*/
template<template<typename> class T>
struct quux<T<bool>>
{
static_assert( false ,
"Please don't use quux with a template with a bool parameter" );
};
答案 0 :(得分:4)
无需单独专业化:
template<typename T>
struct bar
{
static_assert( !std::is_same<T, char>::value,
"No, you can't instantiate bar with char" );
};
编辑:为了回应您的编辑,再次类似的事情:
template<template<typename> class T, typename U>
struct quux<T<U>>
{
static_assert( !std::is_same<U, bool>::value ,
"Please don't use quux with a template with a bool parameter" );
};
答案 1 :(得分:1)
您可以添加另一个虚拟模板参数:
#include <type_traits>
template<typename T,typename=void>
struct bar
{
/* something useful for the user */
};
template<typename U>
struct bar<char,U>
{
static_assert( std::is_same<U,void>::value && false, "No, you can't instantiate bar with char" );
};
int main()
{
bar<int> b;
}