考虑以下示例代码,用于重载operator<<的class A
#include <iostream>
class A {
template <typename T>
friend A &operator<<(A &a, const T &t)
{
std::cout << t << std::endl;
return a;
}
friend A &operator<<(A &a, const std::string &t)
{
return operator<<<std::string>(a, t + "x");
}
};我的意图是第二个操作符显式调用第一个操作符。
但是,在g++ 7.4中,这在
在函数'A& operator<<(A&,const string&)‘中: 无法定义的“operator<<” (a,t+ "x"); 财政、财政、金融、金融、商业、金融等领域的自愿性、商品性、自愿性、 token =‘token 10’>标记前的预期主表达式 (a,t+ "x"); /T1559.2-1995
但是,我不明白为什么这不应该编译。
发布于 2019-11-08 01:35:25
调用一个函数而不是调用一个操作符。
#include <iostream>
class A {
template <typename T>
static A &print(A &a, const T &t)
{
std::cout << t << std::endl;
return a;
}
template <typename T>
friend A &operator<<(A &a, const T &t)
{
return print(a, t);
}
friend A &operator<<(A &a, const std::string &t)
{
return print(a, t + "x");
}
};发布于 2019-11-08 01:36:04
类中的朋友函数不暴露于任何作用域.朋友注入曾经是一种东西(在ADL发明之前),但是现在除了ADL之外,没有其他方法来调用它们,除非您事先声明它们。在这种情况下,解决办法是事先声明类之外的模板函数。
class A;
template <typename T>
A &operator<<(A &a, const T &t);发布于 2019-11-08 02:47:11
您似乎希望专门化模板函数,但您做得不太对。它应该更像这样:
template <> friend A& operator<< <std::string>(A &a, const std::string &t)
{
// Print in here some how. It's not exactly clear to me how you intend to
// do this, as doing something like a << t will create infinite recursion
// finally, return a
return a;
}另一个选项是切换函数的顺序,在创建第一个函数之后创建模板函数:
friend A &operator<<(A &a, const std::string &t)
{
// Again, still not sure what you want to do here
// I just want to stress again though, don't do something
// like a << t, or operator<<(a,t)
// That will crash hard and fast, as there is no way to resolve
// it. It will create infinite recursion
return a;
}
template <typename T>
friend A &operator<<(A &a, const T &t)
{
std::cout << t << std::endl;
return a;
}我的意图是第二个操作符显式调用第一个操作符。
因此,首先,在这种情况下,您需要实际需要第一个选项。
其次,要做到这一点,您需要为t选择一个类型。你会这样做的:
operator<< <SomeType>(a,t);请记住,t需要成为隐式转换 to SomeType。否则,需要通过调用构造函数来创建SomeType:
operator<< <SomeType>(a,SomeType(/* parameters to construct a SomeType ... */));注意:做类似operator<< <SomeType>(a,t + "x")的事情总是会变成无限递归,最终会崩溃。这是因为t + "x"总是一个std::string。这意味着编译器总是无限地调用这个函数的重载,直到它最终从堆栈溢出崩溃。所以别那么做。
https://stackoverflow.com/questions/58758932
复制相似问题