【发布时间】:2023-04-04 05:54:01
【问题描述】:
我试图简化在编译时检查一个值到新类型的转换是否保留了该值。 STL中可能有一些东西可以为我做到这一点,但我没有看到它,所以我写了一个。它可以工作,但我想将它转换为一个类,以使其对其他人的使用更简单。我无法让它工作,我觉得我错过了一些明显的东西。
这很好用:
template <typename T, typename Q>
constexpr bool checkV(const Q x)
{return x == (T)x && ((x < 0) == ((T)x < 0));}
static_assert(checkV<unsigned int>(-7), "No");
但通话很笨拙,所以我想要更像
CheckIt<unsigned int>(-7)
所以我尝试了
template<typename T>
class CheckIt {public:
template<typename Q>
constexpr CheckIt(const Q x) {static_assert(checkV<T>(x), "No");}
};
我尝试了 const 和 constexpr 的各种组合(发现参数不能是 constexpr,这很烦人)。我尝试的一切都会导致 g++ 抱怨 x 不是构造函数中的常量表达式。
我错过了什么? checkv 和构造函数都始终使用常量调用,例如 -7。 checkv() 很高兴在编译时进行评估,我看不出在哪里使用构造函数进行包装,这会给编译器增加任何额外的负担,但显然确实如此。注意我需要它在 C++11 中工作,但我看不出以后的版本会在哪里提供帮助。我在运行时使用断言检查没有问题,但我想要常量的编译时解决方案。 TIA。
【问题讨论】:
-
x必须是模板参数。 -
即使函数本身是常量表达式,您也错过了函数参数不是常量表达式。我想写
static_assert(checkV<unsigned int>(-7), "No");将是 c++11 的唯一选择 -
I want the compile time solution for constants- 所以要检测参数是否为常量,然后使用static_assert?如果它应该只是常量,请使用模板。 -
这并没有解决问题,但在
checkV的正文中,除了两个强制转换中的括号外,所有括号都是多余的。 -
将
x作为函数参数传递永远不会起作用,因为它是一个变量,而不是一个常量表达式。
标签: c++ static-assert