gpt4 book ai didi

c++ - 当通过引用访问时,Constexpr 成员函数返回不被视为 constexpr 的模板参数

转载 作者:行者123 更新时间:2023-11-30 05:33:03 25 4
gpt4 key购买 nike

当我声明一个模板类时,我可以在 constexpr 成员函数中使用任何非类型模板参数,例如:

template <int Value>
struct Foo {
constexpr int value() const { return Value; }
};

然后我可以稍后使用这个函数来初始化 constexpr 变量,如下所示:

template <int Value>
void use_value(Foo<Value> foo) {
constexpr int baz{ foo.value() };
}

int main() {
Foo<10> bar;
use_value(bar);
}

我不明白的是,当我通过引用获取 foo 时...

template <int Value>
void use_value(Foo<Value>& foo) { // by ref
constexpr int baz{ foo.value() };
}

int main() {
Foo<10> bar;
use_value(bar);
}

...clang 会告诉我 foo.value() 不是常量表达式!

test.cpp:8:24: error: constexpr variable 'baz' must be initialized by a constant expression
constexpr int baz{ foo.value() };
~~^~~~~~~~~~~~~
test.cpp:13:5: note: in instantiation of function template specialization 'use_value<10>'
requested here
use_value(bar);

为什么会这样?这是否与以下事实有关:在第一个示例中,编译器能够跟踪 foo 的整个生命周期,而当通过引用获取时,程序的其他部分可能会以某种方式更改实例影响 foo.value() 的constexpr-ness?虽然这里显然不是这种情况(考虑到模板特化,无法更改 Value 的值),但我不确定您是否真的可以通过篡改来“破坏”constexpr 成员函数在某些情况下,实例正在执行。

编辑

好的,所以引用对 constexpr 不利,因为它们有一个运行时位置 - 并且 constexpr 值被硬编码在生成的可执行文件中。持续引用怎么样?这有效:

int main() {
constexpr int foo2{5};
int const& bar2{ foo2 };
}

但是对于 Foo 类,更改对 const 的引用将无济于事:

template <int Value>
void use_value(Foo<Value> const& foo) { // const ref
constexpr int baz = foo.value();
}

我得到了同样的编译器错误。这里有什么区别?

最佳答案

通过引用传递的东西不能是 constexpr。并且,对于实际用作 constexpr 的函数,函数中使用的所有参数和对象也必须是 constexpr。现在,由于引用(甚至是模板对象的引用)永远都不能是 constexpr,这意味着更好的选择是让编译器抛出错误并让开发人员知道,而不是另一种选择生成函数的非 constexpr 版本。

这是因为引用意味着它必须有一个运行时内存位置(参见 C++11 右值和左值,以及右值引用)。如果某些东西符合 constexpr 的条件,则意味着它仅在编译时已知和使用,并且结果将以与硬编码数字或字符串相同的方式烘焙到生成的可执行文件中。

编辑:

常量引用 (const&) 仍然是引用。 const& 充当类似于常规引用的参数限定符,并且仍然需要运行时内存位置 - const& 对象必须“引用”另一个对象。参见 What is a constant reference? (not a reference to a constant)

在您的示例中,const& 依赖于 constexpr,这很好。如果 constexpr 依赖于 const& 它将不起作用。

关于c++ - 当通过引用访问时,Constexpr 成员函数返回不被视为 constexpr 的模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34932906/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com