C++模板中的右值临时值

发布于 2024-09-04 06:19:36 字数 358 浏览 7 评论 0原文

您能否解释一下以下机制之间的区别:

int function();

template<class T>
void function2(T&);

void main() {
    function2(function()); // compiler error, instantiated as int &

    const int& v = function();
    function2(v); // okay, instantiated as const int&
}

我关于实例化的推理是否正确? 为什么不首先实例化为 const T& ?

谢谢

Can you please explain me the difference between mechanism of the following:

int function();

template<class T>
void function2(T&);

void main() {
    function2(function()); // compiler error, instantiated as int &

    const int& v = function();
    function2(v); // okay, instantiated as const int&
}

is my reasoning correct with respect to instantiation?
why is not first instantiated as const T&?

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夏尔 2024-09-11 06:19:37

在 function2 返回后的这一行中

function2(function()); 

,传递给它的参数的值可能会发生变化,但由于 function() 返回并且它只是分配给一个临时变量,但是这个临时变量超出范围后会发生什么问题,这就是编译器抱怨的原因。

In this line

function2(function()); 

after function2 returns, the argument that passes to it might have its value change, but since function() returns and it's just assigned to a temporary variable, but what would happen to this temporary variable after it goes out of scope is the problem, that's why the compiler complaints.

云胡 2024-09-11 06:19:37

要编译第一个调用,需要使用 T&& 定义 function2。参数 - 这是右值,对临时对象的引用。第二次调用时,v是左值引用,就可以了。如果您的编译器不支持右值引用,则第一次调用可能仅使用 T 参数进行编译,而不使用引用。

To compile the first call, it is necessary to define function2 with T&& parameter - this is rvalue, reference to temporary object. In the second call, v is lvalue reference, it is OK. If your compiler doesn't support rvalue references, the first call may be compiled only with T parameter, without reference.

坏尐絯℡ 2024-09-11 06:19:36

因为 function 返回一个非常量值。只有对象可以是 const,因为它们存储一些状态,如果不是 const,则可以对其进行修改。你返回的不是一个对象,而是一个纯值。从概念上讲,它们是不可修改的(例如,像枚举常量),但它们不是 const 限定的(又像枚举常量)。

Because function returns a non-const value. Only objects can be const, because they store some state that could be modified if it weren't const. What you return there is not an object, but a pure value. Conceptually, they are not modifiable (like enumeration constants, for example), but they are not const qualified (like, again, enumeration constants).

往昔成烟 2024-09-11 06:19:36

我认为您可能会对右值和 const 限定符感到困惑。 function 返回一个 int 类型的非常量右值临时值,因此编译器将 T 推断为 int,正如它应该的那样。正如您所指出的,您可以将临时值绑定到 const ref (c++03 12.2/5),但编译器不会添加 cv 限定符来使函数调用格式良好。由于您无法控制模板功能,因此有两种方法可以解决此问题(除了您发布的解决方案之外)。

(1)显式模板参数:function2(function())

(2)cv限定返回:const int function();

这两种方案都很好形成。恕我直言,(1)似乎是更好的解决方案,因为(2)是非常规且愚蠢的。

编辑:实际上,推导的类型可以比 ref 模板参数的参数更具 cv 限定性,但前提是类型推导否则会失败 (c++03 14.8.2.1/3)。在这种情况下,类型推导不会失败,但会导致格式错误的函数调用(SFINAE 不适用,因为模板函数特化本身没有格式错误)。

如果模板作者的意图是不修改参数,则应将其声明为 const 引用参数,因此这可能是模板库中的错误,或者它可能会修改参数,在这种情况下,您所做的将当函数尝试修改参数时失败。

编辑:正如 FredOverflow 指出的那样,非类右值始终不受标准 3.10/9 的 cv 限定。因此,在 gcc 4.3 下工作的 (2) 实际上是一个编译器错误(根据 FredOverflow,gcc <4.5)。

I think that you might be confused between rvalues and the const qualifier. function returns a non-const rvalue temporary of type int, so the compiler deduces T to be int, as it should. As you point out, you can bind a temporary to a const ref (c++03 12.2/5), but the compiler will not add cv qualifiers to make a function call well formed. Since you can't control the template function, there are two ways around this (in addition to the solution you posted).

(1) Explicit template parameters: function2<const int>(function())

(2) cv qualify return: const int function();

Both of these solutions are well formed. (1) seems the better solution, IMHO, since (2) is unconventional and silly.

Edit: Actually, the deduced type can be more cv-qualified than the argument for a ref template argument, but only if type deduction would otherwise fail (c++03 14.8.2.1/3). In this case, type deduction doesn't fail, but results in a malformed function call (SFINAE does not apply, because the template function specialization itself is not malformed).

If the intent of the template author was to not modify the argument, it should be declared as a const reference argument, so this may be a bug in the template library, or it may modify the argument, in which case what you are doing will fail where the function attempts to modify the argument.

Edit: As FredOverflow points out, non-class rvalues are always cv unqualified by the standard 3.10/9. So (2), which works under gcc 4.3, is actually a compiler bug (gcc <4.5, according to FredOverflow).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文