c++ - `constexpr` 参数在编译时未知时不调用构造函数

标签 c++ c++11 c++14

目前我正在阅读 Scott Meyers 的 Effective Modern C++(第 15 项 - 尽可能使用 constexpr。)。作者说:

When a constexpr function is called with one or more values that are not known during compilation, it acts like a normal function, computing its result at runtime. This means you don’t need two functions to perform the same operation, one for compile-time constants and one for all other values. The constexpr function does it all.

我在 http://coliru.stacked-crooked.com/ 中尝试了以下代码片段

#include <iostream>

class Point
{
    public:
        constexpr Point(double a, double b) noexcept
            : _a(a), _b(b)
        {
        }

        void print() const noexcept
        {
            std::cout << "a -> " << _a << "\tb -> " << _b << std::endl;
        }

    private:
        double _a;
        double _b;
};

double get_a() noexcept
{
    return 5.5;
}

double get_b() noexcept
{
    return 5.6;
}


int main()
{
    constexpr Point p1(2.3, 4.4);
    p1.print();
    int a = get_a();
    int b = get_b();
    constexpr Point p2(a, b);
    p2.print();
    return 0;
}

在创建 p1 对象的情况下,一切都按预期进行:参数是已知的编译时间并且成员被正确初始化。在创建 p2 对象的情况下,虽然我们在编译时不知道 ab 变量的值,但它应该在我的理解,因为构造函数应该充当普通函数。但是我收到以下错误消息:

main.cpp: In function 'int main()'
main.cpp:38:28: error: the value of 'a' is not usable in a constant expression
     constexpr Point p2(a, b);
                            ^
main.cpp:36:9: note: 'int a' is not const
     int a = get_a();
         ^
main.cpp:38:28: error: the value of 'b' is not usable in a constant expression
     constexpr Point p2(a, b);
                            ^
main.cpp:37:9: note: 'int b' is not const
     int b = get_b();

Coliru 使用 gcc 编译器。 所以,我不明白是什么问题。也许我错过了什么......

最佳答案

来自 cppreference (强调我的):

A constexpr variable must satisfy the following requirements:

  • its type must be a LiteralType.
  • it must be immediately initialized
  • the full-expression of its initialization, including all implicit conversions, constructors calls, etc, must be a constant expression

在你的例子中......

constexpr Point p2(a, b);

...ab 不是常量表达式。为了使它们成为常量表达式,需要将get_aget_bab标记为constexpr:

constexpr double get_a() noexcept
{
    return 5.5;
}

constexpr double get_b() noexcept
{
    return 5.6;
}

constexpr int a = get_a();
constexpr int b = get_b();
constexpr Point p2(a, b);

关于c++ - `constexpr` 参数在编译时未知时不调用构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46618980/

相关文章:

c++ - Sublime Text 中的 ctags

c++ - 字符串构造函数的无限精度和指定的舍入和比例

c++ - 避免使用大量全局变量或使它们易于访问和修改的最佳方法

c++ - 为什么clang拒绝可变参数模板 friend 功能

c++ - 与 std::memcmp 或 string::compare 进行子串比较?

c++ - ->* 运算符应该在何时何地重载?

c++ - __thiscall 关键字的用途是什么?

C++将函数模板作为参数传递给其他函数作为回调

c++ - C++11 <type_traits> 模板参数类型推导失败

c++ - 无法在未指定捕获默认值的 lambda 中隐式捕获变量