我有一个类似的序列化功能:
class Serializer
{
template<typename T>
T read(const std::string& source)
{
if constexpr(std::is_same<T, int>::value)
{
return std::stoi(source);
}
else if constexpr(std::is_same<T, float>::value)
{
return std::stof(source);
}
else
{
assert(false);
return T();
}
}
};
我想做的是将运行时断言替换为编译时断言(例如static_assert),以检测在编译时缺少实现。全功能专业化将是检测缺少的实现的一种选择,但是对我而言,这并不是真正的选择,因为它是一个成员函数,可能需要来自封装类的一堆成员。有什么方法可以执行类似静态断言的操作,如果未命中constexpr分支,该断言不会被触发?
答案 0 :(得分:3)
static_assert( std::is_same<T, int>::value || std::is_same<T, float>::value );
解决了演示的问题。
通常,不可以,else
分支中不能包含static_assert(false)
。您可以通过黑客手段允许类似的行为,但是它们的合法性值得怀疑。
可能最简单的解决方案是不从else
返回,并且当您的函数不返回值时让编译器发出警告。
您可能想static_assert(!std::is_same<T,void>{})
只是为了抓住这种情况。 ;)
答案 1 :(得分:3)
由于static_assert(false);
不依赖于模板参数,因此编译器可以在两阶段查找的实例化点之前检查此断言。
因此,例如,以下static_assert
可以正确地用于您的目的:
class Serializer
{
public:
template<typename T>
T read(const std::string& source)
{
if constexpr(std::is_same<T, int>::value)
{
return std::stoi(source);
}
else if constexpr(std::is_same<T, float>::value)
{
return std::stof(source);
}
else
{
static_assert(!std::is_same<T, T>::value);
}
}
};