<< 运算符重载和模板特化

<< operator overloading and template specialization

作为学习目的的一部分,我只是在玩模板特化和运算符重载

#include <iostream>

template<class T>
void operator<<(std::ostream& COUT,T val)
{
   std::operator<<(COUT,val); //works for basic data types
}

//specializing for const char*
template<>
void operator<<(std::ostream& COUT,const char* val)
{
    std::operator<<(COUT,val);
}
int main()
{
    std::cout<<"samplestring"; //getting error here
    return 0;
}

我收到以下错误,我无法弄清楚。

<source>:17:14: error: ambiguous overload for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'const char [13]')
   17 |     std::cout<<"samplestring";
      |     ~~~~~~~~~^~~~~~~~~~~~~~~~
      |          |     |
      |          |     const char [13]
      |          std::ostream {aka std::basic_ostream<char>}

这里有什么问题

谢谢..!

问题是标准库已经定义了operator<<(std::ostream& COUT,const char* val)

所以现在有两个符号

std::operator<<(std::ostream& ostream,const char* val);
operator<<(std::ostream& COUT,const char* val); // YOURS

因为符号不同,所以没有multiple-definition个错误。

对于调用 std::cout << "Hello",编译器搜索当前在调用站点定义的所有 operator<< 函数。看起来它只是你的函数,但编译器还会查看定义传递参数的所有命名空间。在这种情况下,它是 std:: 命名空间,编译器会在其中找到 STL 版本。这称为参数依赖查找(ADL)。

因为这两个函数都是模板,而且没有一个比另一个更专业,所以调用不明确。

请不要使用所有大写字母作为变量COUT,这通常是为宏保留的,one-letter 模板参数除外T

//works for basic data types

那也不对,std::cout<<5; 不会用 T 调用您的定义。因为存在 std::ostream::operator<<(int v) 方法。发生相同的查找,但由于此方法不是模板,因此它是更好的候选者,因此被选中。您的模板函数永远不会被调用。