我试图通过一种方法更改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。谁错了?
答案 0 :(得分:5)
这似乎是一个 g ++ 错误,可以从g ++ 5.1到g ++ 7.0重现。我认为这是一个错误,因为这种行为似乎是荒谬的。我玩了片段,我相信如果变量是全局的,编译器只执行第一个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 ++错误跟踪器上报告了这个问题,如bug #80039。