<< 运算符重载和模板特化
<< 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)
方法。发生相同的查找,但由于此方法不是模板,因此它是更好的候选者,因此被选中。您的模板函数永远不会被调用。
作为学习目的的一部分,我只是在玩模板特化和运算符重载
#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)
方法。发生相同的查找,但由于此方法不是模板,因此它是更好的候选者,因此被选中。您的模板函数永远不会被调用。