这个问题已经讨论了几次,但我发现的所有解决方案要么不起作用,要么基于boost的静态断言。我的问题很简单。我有一个类,我只想允许真正的类型(double和float)。如果我尝试使用float或double以外的类型实例化类,我想要一个编译时错误。我正在使用Visual C ++ 11.这是我尝试过的:
template <typename RealType>
class A
{
// Warning C4346
static_assert(std::is_same<RealType, double>::value || std::is_same<RealType, float>::value);
}
template <typename RealType>
class A
{
// Error C2062: type 'unknown' unexpected
static_assert(decltype(RealType) == double || decltype(RealType) == float);
}
有什么想法吗?提前谢谢!
答案 0 :(得分:29)
在您的第一个示例中,static_assert
应该采用第二个参数,该参数将是字符串文字,否则它被视为失败(编辑:删除第二个参数是合法自C ++ 17)。而这第二个论点不能违约。
你的第二个例子是不正确的,原因如下:
decltype
旨在用于表达式,而不是用于类型。==
进行比较,正确的方法是首次尝试使用std::is_same
时尝试的方法。因此,正确的做法是:
#include <type_traits>
template <typename RealType>
class A
{
static_assert(std::is_same<RealType, double>::value || std::is_same<RealType, float>::value,
"some meaningful error message");
};
此外,我打赌你试图将模板限制为浮点值。为此,您可以使用特征std::is_floating_point
:
#include <type_traits>
template <typename RealType>
class A
{
static_assert(std::is_floating_point<RealType>::value,
"class A can only be instantiated with floating point types");
};
作为奖励,请this online example。
答案 1 :(得分:21)
我见过的一个解决方案是在类型别名中使用std::enable_if
。类似的东西:
using value_type = typename std::enable_if<
std::is_same<float, RealType>::value ||
std::is_same<double, RealType>::value,
RealType
>::type;
value_type
仅在RealType
完全float
或double
时才存在。否则,类型未定义,编译失败。
答案 2 :(得分:5)
这样它还允许对各种类型进行专业化:
template<typename T, typename Enable = void>
class A {
/// Maybe no code here or static_assert(false, "nice message");
};
/// This specialization is only enabled for double or float.
template<typename T>
class A<T, typename enable_if<is_same<T, double>::value || is_same<T, float>::value>::type> {
};