任何type_traits或方法都可以找出这些参数是否为constexpr?
实施例
size_t fibo_runtime(size_t num)
{
//implementation
}
constexpr size_t fibo(size_t num)
{
return is_constexpr<size_t>::value ? //this type traits looks weird and unreasonable
(num > 1 ? fibo(num - 1) * num : 1) :
fibo_runtime(num);
}
constexpr可以应用于constexpr参数和 参数在运行时确定。然而, 在运行时,递归可能效率不高。
我们还是要分开执行 constexpr函数的运行时和编译时间? 如果我们不能这样做,我们是否可以强制执行用户 无法使用constexpr函数来执行某些运行时 评价
答案 0 :(得分:0)
常量表达式(constexpr
)的本质是常量。所以运行时评估与否,它们不会改变它们的任何行为,评估永远不会在运行时完成。
如果在运行时使用constexpr
函数(不是简单地通过直接调用它),那么它将被称为普通函数,因为在运行时,表达式无法自然地解析为常量。 / p>
如果你想根据编译时或运行时实现一些不同的实现,它会(如果你实现它)对开发人员来说真的很不安,因为根据你调用它的方式,函数不会有相同的行为!因此很明显,这种行为不会/不会/不应该实施。
如果您想专门编写一个函数进行编译时计算,请使用不同的函数来清楚地表明您的意图。
答案 1 :(得分:0)
在函数中,不可能检查参数以查看完整的调用表达式是否为常量表达式。但是你可以在调用站点实现一个宏来测试同样的东西,在编译时评估为true_type
或false_type
,具体取决于表达式是否为常量表达式
IS_A_CONSTANT_EXPRESSION( fibo(5) ) // is constant
IS_A_CONSTANT_EXPRESSION( fibo(time(NULL) ) // is not constant
详情见this answer另一个问题。 (我自己的回答,为交叉发帖道歉!)
然后你可以实现另一个宏FIBO( expr )
来很好地包装它,并根据需要调用正确的版本。
答案 2 :(得分:-2)
我认为这可能会让你得到你想要的东西
#include <iostream>
template <typename T>
class is_constexpr
{
typedef char true_type ;
struct false_type { true_type _[2] ; } ;
template <typename U>
static true_type has_constexpr( U & ) ;
template <typename U>
static false_type has_constexpr(...) ;
public:
enum { value = ( sizeof(has_constexpr<T>(0)) == sizeof(true_type)) } ;
} ;
int main()
{
constexpr int i = 10 ;
int k = 20 ;
std::cout << is_constexpr<decltype(i)>::value << std::endl ;
std::cout << is_constexpr<decltype(k)>::value << std::endl ;
}
我使用Understanding SFINAE作为参考。
进行更多研究我认为我对问题的其他部分的答案是肯定的,因为它看起来是constexpr
函数模板is not always usable in a constant expression。所以这导致了一个像这样的解决方案,这个有点人为的例子:
template <typename T>
T f2( T num )
{
return num + 1;
}
template <typename T>
constexpr T f1( T num )
{
return num ;
}
template <typename T>
constexpr T f(T num)
{
return is_constexpr<T>::value ? f1(num) : f2(num) ;
}