gpt4 book ai didi

c++ - 模板重载的行为不同于非模板重载

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

有这个:

#include <iostream>

void test(const int& ref){
std::cout << "By reference\n";
}

void test(const int *ptr){
std::cout << "By pointer\n";
}

template<typename T>
void test_template(const T &ref){
std::cout << "By reference\n";
}

template<typename T>
void test_template(const T *ptr){
std::cout << "By pointer\n";
}

int main() {
int *p = 0;
test(p);
test_template(p);
return 0;
}

我得到了输出(使用 g++ 4.8.4):

By pointer
By reference

为什么模板版本的行为不同(是 C++ 缺陷还是编译器错误)?

最佳答案

让您感到困惑的是您的模板并没有完全复制重载的行为。当编译器执行(非模板)重载解析时,它发现 const int*const int& 更匹配,因为 不需要转换指针重载中的int*(不过,两者都有限定符转换,不是那么重要)。

但是,对于您的模板,情况有些不同

这个:

template<typename T>
void test_template(const T &ref){
std::cout << "By reference\n";
}

可以实例化为const int& ref,没错,但也可以实例化为int* const& ref(因为T是const , Tint*,要创建一个 const 指针,请将 const 放在 int* 之后)。比较一下:

template<typename T>
void test_template(const T *ptr){
std::cout << "By pointer\n";
}

其中,T可以实例化为int得到const int*

所以现在编译器必须问自己,哪个是更好的匹配,

  • int* const& ref,或者
  • const int* ptr?

答案是第一个。鉴于在订购模板之前删除了引用和 cv 限定符,我们只剩下比较

  • int* 反对
  • const int*

因此第二个需要从 int*const int* 的类型转换,而第一个则不需要。 (指针语法很奇怪,你记得在我们上面的例子中,剩下的 const 是类型的一部分,而不是限定符)。请注意,如果您将 p 定义为 const int *p = 0;,编译器会选择第二个。

要完全重新创建非模板重载的行为,您必须显式测试 T 是否为指针类型:

template<typename T, typename std::enable_if<!std::is_pointer<T>::value, int>::type = 0>
void test_template(const T& ref){
std::cout << "By reference\n";
}

template<typename T>
void test_template(const T* ptr){
std::cout << "By pointer\n";
}

但是,我认为真正“足够好”的是将 const 移动到 T* 的另一侧以实现指针重载:

template<typename T>
void test_template(const T &ref){
std::cout << "By reference\n";
}

template<class T>
void test_template(T* const ptr){
std::cout << "By pointer\n";
}

这是有效的,因为在订购模板时,首先从类型中删除了 cv 限定符和引用。这给我们留下了

  • T ref 对比

  • T* ptr

    并且 T* 被认为比 T 更专业,因此将根据需要选择第二个。

关于c++ - 模板重载的行为不同于非模板重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34358941/

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