在模板实例化期间,文字值不被视为常量表达式

时间:2018-03-19 08:19:45

标签: c++ templates metaprogramming template-meta-programming

这段代码应该使用模板元编程来检查float在编译时是否等于int的一半:     #include

struct A {
    constexpr static bool value = true;
};

struct B {
    constexpr static bool value = false;
};

template<int i>
struct Meta {
    constexpr static int value = i/2;
    constexpr static bool func(float n) {
        return std::conditional_t<n==value,A,B>::value;
    }
};


int main( int argc, const char *argv[] ) {
    constexpr bool b = Meta<4>::func(2);
    std::cout << b << std::endl;
    return 0;
}

但它拒绝编译。编译器说n is not a constant expression

test.cpp: In substitution of ‘template<bool _Cond, class _Iftrue, class _Iffalse> using conditional_t = typename std::conditional::type [with bool _Cond = (n == (float)2); _Iftrue = A; _Iffalse = B]’:
test.cpp:15:50:   required from ‘static constexpr int Meta<i>::func(float) [with int i = 4]’
test.cpp:21:36:   required from here
test.cpp:15:50: error: ‘n’ is not a constant expression
         return std::conditional_t<n==value,A,B>::value;
                                                  ^~~~~
test.cpp:15:50: note: in template argument for type ‘bool’ 
test.cpp: In function ‘int main(int, const char**)’:
test.cpp:21:36:   in constexpr expansion of ‘Meta<4>::func((float)2)’
test.cpp:21:38: error: constexpr call flows off the end of the function
     constexpr int b = Meta<4>::func(2);
                                      ^

这里有什么问题?传递给Meta::func的值是字面值。它应该被视为常数。

我感兴趣的是如何在编译时基于值执行不同的操作。这应该是可能的,因为在编译时可以获得计算输出所需的所有输入。

我想知道如何根据编译时的值执行不同的操作(可能涉及类型)。这应该是可能的,因为在编译时可以获得计算输出所需的所有输入。

1 个答案:

答案 0 :(得分:4)

问题是生成一个函数需要使用常量表达式(如文字所示)以及可变修改值(例如以前的计算结果)来调用

函数的constexpr属性保证在编译时评估函数, 如果 ,因为 all 参数是常量表达式。如果它们中没有任何一个,则该函数用作在运行时计算的普通函数。即使你从不以这种方式使用函数,它仍然必须能够处理大小写,因此函数参数(n)一般不能用作constexpr,因此n == value } 都不是;如果在if constexpr或(在编辑之后)用作模板参数,则无关紧要。

然而,实际上,内部if constexpr已经过时了:您使用编译时常量提供constexpr函数,因此上述保证适用,并且您的函数将在编译时进行评估,无论您是否使用if constexpr,您的功能都可以简化为:

constexpr static bool func(float n)
{
    return n == value;
}

请注意,如果没有按预期结果出现,则您无法将结果分配给constexpr bool ...

已在评论中表示已经提出的问题,但重要的是要再次暗示:还要注意浮动算术的四舍五入问题以及通过完全平等来比较这些价值观!