通过static_assert实施模板类型
我想了解static_assert
的用处,并且我想知道它是否可以帮助我强制执行设计,如果是这样,如何实现。通过static_assert实施模板类型
我有一个通用模板类,它隐藏了自己的实现内部另一个模板类,这是部分专用的基于模板类型的大小。下面是该外观设计的简要概述:
template <class T, size_t S = sizeof(T)>
struct Helper;
template <class T>
struct Helper<T, sizeof(long)>
{
static T bar();
};
// ... other specializations ...
template <class T>
class Foo
{
public:
T bar()
{
return Helper<T>::bar();
}
};
富如果T
大小由助手的专业化支持,才支持。例如,Foo<long>
和Foo<unsigned long>
都支持。但是,假设用户试图构建一个Foo<bool>
。通常,这会产生错误,因为助手对于bool
没有定义,这是预期的行为。
在这个设计中有没有什么办法可以使用static_assert
为这个接口的用户提供更多有用的错误?
此外,我想也限制用户使用特定类型,即使尺寸可能是正确的。例如,不应允许使用Foo<float>
。现在,我知道强制执行此操作的唯一方法是通过文档中的大胆评论。 :)
我在这里通过合并的答案和注释想通了这个问题更好的解决方案。
我可以定义一个静态类型检查就像这样:
template <class A, class B>
struct CheckTypes
{
static const bool value = false;
};
template <class A>
struct CheckTypes<A, A>
{
static const bool value = true;
};
不知道这样的结构在标准库中已经存在。不管怎么说,然后在美孚,我可以通过检查类型和大小:
static_assert((sizeof(T) == sizeof(long) || sizeof(T) == sizeof(int)) && !CheckTypes<T, float>::value, "Error!");
它呢,std :: is_same –
使用sizeof是不安全的。它只是大小。 long和int可能具有相同的大小,而只包含int的随机结构也会具有相同的大小。 –
如果它只能为模板类的专业化工作,然后有默认的模板类提高静态断言:
template <class T, size_t S = sizeof(T)>
struct Helper
{
static_assert(sizeof(T) == -1,"You have to have a sepecialization for Helper!");
}
如果没有默认的模板类才会被选择一个更好的专业化,因此断言将会上升。
您可以使用相同的技术来禁止类型,但您需要另一个将用于静态断言检查的模板参数。
template <class T, class G = T, size_t S = sizeof(T)>
struct Helper
{
static_assert(sizeof(G) == -1,"You have to have a sepecialization for Helper!");
}
template <class G>
struct Helper<float,G>
{
static_assert(sizeof(G) == -1,"You can't use float !");
}
template <>
struct Helper<int>
{
//This is a good specialization
};
然后,您可以用这些变量试试:
Helper<bool> a; //"You have to have a sepecialization for Helper!"
Helper<float> b; //"You can't use float !"
Helper<int> c; //compiles OK
http://en.cppreference.com/w/cpp/header/type_traits
std::is_base_of
和std::is_convertible
可以与你的第一个问题和第二个帮助,
static_assert(!std::is_same<float,T>(),"type can't be float");
希望这可以帮助别人谁发现这个问题,假设OP可能在4年内找到答案sin它被问:) :)
更一般地想一想,它只是支持整数类型?没有'char','bool','float'等等? – Rapptz
搜索模板类型约束或“概念”。在最后一刻从C++ 11中删除了这样做的工具。尽管如此,自动获取类似结果的方法却较少。 – luke
@Rapptz,'char','int'和'long'以及它们的'unsigned'版本应该被支持。如果sizeof(int)== sizeof(long)== sizeof(unsigned long)',那么代码对于int,long和unsigned long是相同的。 – Zeenobit