gpt4 book ai didi

c++ - 在模板实例化期间重载查找

转载 作者:太空狗 更新时间:2023-10-29 21:39:03 26 4
gpt4 key购买 nike

我有一段代码可以使用 icc 或 visual c++ 编译,但当我使用 gcc 或 clang 时却没有。

问题来自于 gcc/clang 需要 bindTo(std::string& s, const int& i) 的事实在 A<T>::bind(T& t) 之前定义或 callBindTo(T& t)定义,而不仅仅是在代码实例化之前。

我的问题是:为什么 Visual 和 icc 不需要它?哪个编译器具有符合标准的正确行为?

#include <string>

template <typename T>
class A
{
public:
static void bind(T& t);
};

template <typename T>
void A<T>::bind(T& t)
{
std::string s;
bindTo(s, t);
}

template <typename T>
void callBindTo(T& t)
{
std::string s;
bindTo(s, t);
}

void bindTo(std::string& s, const int& i)
{
s = i;
}

int main()
{
int i;
A<int>::bind(i);
callBindTo(i);
}

最佳答案

GCC 和 Clang 有正确的实现。正如评论提示的那样,名称 t在实例化期间查找,在第二个名称查找阶段,当 T==int .这不会为 Argument-Dependent Lookup 引入任何额外的命名空间。因此,编译器必须查找 bind 的所有声明。 ,在全局命名空间中,直到实际使用它的地方。

最后一部分很重要。查找的范围 由模板定义的位置决定,而不是由第一个实例化的位置决定。这是一件好事。如果有 5 个实例化,5 个越来越大的重载集会怎么样?您必须每次都实例化模板,重做重载解析,并可能得到 5 个不同的结果。

如果您认为这还不够糟糕,您会如何处理名称修改?你会有 callBindTo<int>callBindTo<int> , 两个实例只能通过 bind 的重载集来区分在它们的实例化点。

不,当前的规则是合理的。是的,Argument Dependent Lookup 可以添加额外的 namespace ,这很棘手,但是 callBindTo<std::string> 的所有实例化添加相同的命名空间 std .通过该示例,我们看到您将函数称为 bindTo 是件好事。而不是 bind - 你差点拖进去std::bind .

关于c++ - 在模板实例化期间重载查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33889367/

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