gpt4 book ai didi

c++ - 全局函数模板重载和 const 参数

转载 作者:行者123 更新时间:2023-11-30 03:06:04 24 4
gpt4 key购买 nike

如果我编译(gcc 4.6.0)并运行这段代码:

#include <iostream>

template <typename T> void F(/* const */ T& value) {
std::cout << "T & " << value << std::endl;
}

template <typename T> void F(/* const */ T* value) {
std::cout << "T * " << value << std::endl;
F(*value);
}

int main(int argc, char* argv[]) {
float f = 123.456;
float* pf = &f;

F(pf);

return 0;
}

我得到以下输出:

T * 0x7fff7b2652c4
T & 123.456

如果我取消注释 const 关键字,我会得到以下输出:

T & 0x7fff3162c68c

我可以将 float* pf = &f; 更改为 const float* pf = &f; 以再次获得原始输出,这不是问题。

我想了解的是,为什么在使用 const 修饰符进行编译时,重载决策认为 const T& valueconst T* value 更匹配非常量 float*?

最佳答案

在重载解析期间,不需要转换的重载胜过需要一些转换的重载,即使这些转换是微不足道的。引用 C++03 标准,[over.match.best] (§13.3.3/1):

Define ICSi(F) as follows:

  • if F is a static member function, ICS1(F) is defined such that ICS1(F) is neither better nor worse than ICS1(G) for any function G, and, symmetrically, ICS1(G) is neither better nor worse than ICS1(F); otherwise,
  • let ICSi(F) denote the implicit conversion sequence that converts the i-th argument in the list to the type of the i-th parameter of viable function F. 13.3.3.1 defines the implicit conversion sequences and 13.3.3.2 defines what it means for one implicit conversion sequence to be a better conversion sequence or worse conversion sequence than another.

Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then

  • for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,
  • F1 is a non-template function and F2 is a function template specialization, or, if not that,
  • F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 14.5.5.2, or, if not that,
  • the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type of F2 to the destination type.

const 存在时,为了调用带引用的重载,不需要转换——T 被推断为 float* 并且参数是 float* const&。但是,为了调用带指针的重载,需要将 float 转换为 float const 以使所述重载可行。因此,采用引用的重载获胜。

当然,请注意,如果 pf 被更改为 float const*,行为将回到您预期的方式,因为重载采用指针将不再需要转换。

关于c++ - 全局函数模板重载和 const 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7034297/

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