【问题标题】:Change constexpr object member using method fail使用方法失败更改 constexpr 对象成员
【发布时间】:2017-08-04 15:18:11
【问题描述】:

我正在尝试通过一种方法更改 constexpr 对象成员的值,但我不明白为什么它在这种特定情况下不起作用:

#include <iostream>

struct test
{
    int m_counter = 0;

    constexpr test()
    {
        m_counter++;
        m_counter++;
        increment();
        increment();
        increment();
    }

    constexpr void increment()
    {
        m_counter++;   
    }

    constexpr int value() const
    {
        return m_counter;
    }
};

template<int value>
constexpr void check()
{
    std::cout << value << std::endl;
}

// constexpr test t; // value = 3, why ?

int main()
{
    constexpr test t; // value = 5, ok
    check<t.value()>();
}

当我在全局范围内创建对象时,我不明白为什么值为 3。 msvc 和 clang 在这两种情况下都显示 5,但 gcc 不显示。谁错了?

【问题讨论】:

  • 另外,您使用的是哪个版本的 GCC?你传递给 GCC 的标志是什么?哪个版本的 Clang,以及你传递给它的标志是什么?与 MSVC++ 一样吗?最重要的是,我们需要知道您使用的是 C++11 还是 C++14? constexpr 构造函数和函数在两个标准中的行为不同(参见例如 this constexpr reference 了解更多信息)。
  • ...对我来说这可能是一个 gcc 错误
  • checkconstexpr 格式不正确 (NDR);无论check 的模板参数如何,任何涉及标准流的东西都不能是常量表达式。
  • 报告为错误#80039

标签: c++ object gcc c++14 constexpr


【解决方案1】:

这似乎是一个 g++ 错误,可从 g++ 5.1 到 g++ 7.0 重现。我认为这是一个错误,因为这种行为似乎很荒谬。我玩弄了 sn-p,我相信如果变量是全局的,编译器只会执行第一个 increment() 调用,而忽略其他调用:

constexpr test()
{
    m_counter++; // executed
    m_counter++; // executed
    increment(); // executed
    increment(); // NOT executed
    increment(); // NOT executed
}

// [...] will print 3

constexpr test()
{
    m_counter++; // executed
    m_counter++; // executed
    increment(); // executed
}

// [...] will print 3

constexpr test()
{
    m_counter++; // executed
    m_counter++; // executed
}

// [...] will print 2

constexpr test()
{
    m_counter++; // executed
    m_counter++; // executed
    increment(); // executed
    increment(); // NOT executed
    increment(); // NOT executed
    increment(); // NOT executed
    increment(); // NOT executed
    increment(); // NOT executed
}

// [...] will print 3

基本上,构造函数中只有一个increment() 会被执行。添加更多increment() 调用无效。但是,添加更多 m_counter++ 指令将正常工作。

constexpr test()
{
    m_counter++; // executed 
    m_counter++; // executed
    increment(); // executed
    increment(); // NOT executed
    m_counter++; // executed
    m_counter++; // executed
    increment(); // NOT executed
    increment(); // NOT executed
}

// [...] will print 5

我在 g++ 错误跟踪器上将此报告为错误#80039

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多