qua*_*ant 24 c++ templates static-assert c++11 visual-studio-2012
这个问题已经讨论了几次,但我发现的所有解决方案要么不起作用,要么基于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);
}
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?提前致谢!
Mor*_*enn 31
在你的第一个例子中,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");
};
Run Code Online (Sandbox Code Playgroud)
而且,我打赌你试图将模板限制为浮点值.为此,您可以使用特征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");
};
Run Code Online (Sandbox Code Playgroud)
作为奖励,请参考此在线示例.
cHa*_*Hao 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;
Run Code Online (Sandbox Code Playgroud)
value_type只有RealType完全float或者只存在double.否则,类型未定义,编译失败.
不过,我会警告对类型过于严格.模板和它们一样强大,部分原因是它们所做的鸭子打字意味着任何可以按照你想要的方式使用的类型都可以使用.禁用类型以禁用类型通常不会给你带来太大的好处,并且会使事情变得不那么灵活.例如,您将无法使用具有更高精度的类型,如大十进制类型.
这样它还允许各种类型的专业化:
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> {
};
Run Code Online (Sandbox Code Playgroud)