我有一个基类类似于下面的代码.我试图重载<<以与cout一起使用.但是,g ++说:
base.h:24: warning: friend declaration ‘std::ostream& operator<<(std::ostream&, Base<T>*)’ declares a non-template function
base.h:24: warning: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning
Run Code Online (Sandbox Code Playgroud)
我尝试在类声明/原型中添加<<之后的<>.但是,我明白了does not match any template declaration.我一直试图让操作符定义完全模板化(我想要的),但我只能使用以下代码使用操作符手动实例化.
base.h
template <typename T>
class Base {
public:
friend ostream& operator << (ostream &out, Base<T> *e);
};
Run Code Online (Sandbox Code Playgroud)
base.cpp
ostream& operator<< (ostream &out, Base<int> *e) {
out << e->data;
return …Run Code Online (Sandbox Code Playgroud) 我需要使用虚拟<<运算符.但是,当我尝试写:
virtual friend ostream & operator<<(ostream& os,const Advertising& add);
Run Code Online (Sandbox Code Playgroud)
我得到编译器错误
错误1错误C2575:'operator <<':只有成员函数和基数可以是虚拟的
如何将此运算符设为虚拟?
我有一个模板 class A
template <unsigned int m>
class A
{
public:
A(int) {}
};
Run Code Online (Sandbox Code Playgroud)
哪个有构造函数int.我有一个手术:
template<unsigned int m>
A<m> operator+(const A<m>&, const A<m>&)
{
return A<m>(0);
}
Run Code Online (Sandbox Code Playgroud)
但是当我打电话时:
A<3> a(4);
A<3> b = a + 5;
A<3> c = 5 + a;
Run Code Online (Sandbox Code Playgroud)
我想int隐式转换为A,但编译器会抛出错误.
有没有优雅的方法来启用隐式转换而不使用以下解决方案:
a + A<m>(5)operator+<3>(a, 5)C++ 11标准中的§7.3.1.2/ 3(重点是我的):
首先在名称空间中声明的每个名称都是该名称空间的成员.如果非本地类中的友元声明首先声明一个类或函数,那么友元类或函数是最内层封闭命名空间的成员.在非命名查找(3.4.1)或限定查找(3.4.3)之前找不到朋友的名称,直到在该命名空间范围内提供匹配声明(在授予友谊的类定义之前或之后).如果调用了友元函数,则可以通过名称查找找到其名称,该名称查找考虑名称空间中的函数和与函数参数类型相关联的类(3.4.2).如果友元声明中的名称既不是限定语句也不是模板标识,并且声明是函数或详细类型说明符,则确定实体是否先前已声明的查找不应考虑最内层封闭命名空间之外的任何范围.[注意:其他形式的友元声明不能声明最内层封闭命名空间的新成员,因此遵循通常的查找规则.
例:
Run Code Online (Sandbox Code Playgroud)// Assume f and g have not yet been defined. void h(int); template <class T> void f2(T); namespace A { class X { friend void f(X); // A::f(X) is a friend class Y { friend void g(); // A::g is a friend friend void h(int); // A::h is a friend // ::h not considered friend void f2<>(int); // ::f2<>(int) is a friend }; }; // A::f, A::g and A::h are not visible …
我有一个问题是重载<<流操作符,我找不到解决方案:
template<class T, unsigned int TN>
class NVector
{
inline friend std::ostream& operator<< (
std::ostream &lhs, const NVector<T, TN> &rhs);
};
template<class T, unsigned int TN>
inline std::ostream& NVector<T, TN>::operator<<(
std::ostream &lhs, const NVector<T, TN> &rhs)
{
/* SOMETHING */
return lhs;
};
Run Code Online (Sandbox Code Playgroud)
它会产生以下错误消息:
警告:朋友声明'std :: ostream&operator <<(std :: ostream&,const NVector&)'声明一个非模板函数[-Wnon-template-friend]
错误:'std :: ostream&NVector :: operator <<(std :: ostream&,const NVector&)'必须只有一个参数
如何解决这个问题?
非常感谢你.
下面的代码可以正常工作,但我想将ostream&operator <<移到类declearation之外,就像我使用hash :: operator []一样.
#include<iostream>
#include<map>
using namespace std;
template <class T>
class hash {
private:
map<string, T> _map;
public:
T& operator[] (string x);
friend ostream& operator<<(ostream& out, const hash<T> &rhs) { return out << "test"; }
};
template <class T>
T & hash<T>::operator[](string x) {
return _map[x];
}
int main () {
hash<int> myobject;
myobject["a"] = 1;
cout << myobject["a"] << endl;
cout << myobject << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我试过了:
template <class T>
ostream& operator<<(...) {
return …Run Code Online (Sandbox Code Playgroud) 我有这个代码:
template<typename T>
class Listoid{
private:
std::vector<T> list;
public:
typedef typename std::vector<T>::iterator iterator;
iterator begin() {return list.begin();}
iterator end() {return list.end();}
public:
Listoid(T t) {
list.push_back(t);
}
const T operator [](int i){
return list[i];
}
void addElem(T ne){
list.push_back(ne);
}
friend T cons(T new_elem, Listoid<T> list);
};
template<typename T>
Listoid<T> cons(T new_elem, Listoid<T> list){
Listoid<T> new_list(new_elem);
for(typename Listoid<T>::iterator it = list.begin(), e = list.end();
it != e; ++it){
new_list.addElem(*it);
}
return new_list;
}
int main(){
Listoid<int> lista(312);
lista.addElem(22);
Listoid<int> lista2 …Run Code Online (Sandbox Code Playgroud) 我有一个带有私有构造函数和析构函数的模板类:
template <typename T>
class Client
{
private:
Client(...) {}
~Client() {}
template <typename U>
friend class Client<T>& initialize(...);
};
template <typename T>
Client<T> initialize(...)
{
Client<T> client = new Client<T>(...);
}
Run Code Online (Sandbox Code Playgroud)
我不确定朋友的正确语法。有人可以帮忙吗?
在你问之前,是的,函数是在我的模板类的标题中定义的.
这是以下相关部分Example.h:
template<class T, class J, const int X, const int Y>
class Example {
public:
friend std::ostream& operator<<(std::ostream& s, const Example<T,J,X,Y>& b);
}
template<class T, class J, const int X, const int Y>
std::ostream& operator<<(std::ostream& s, const Example<T,J,X,Y>& b) {
// stuff
}
Run Code Online (Sandbox Code Playgroud)
我是这样说的main.cpp:
void foo(Example<A,B,5,5>& b) {
std::cout << b;
}
int main() {
Example<A,B,5,5> b = Example<A,B,5,5>();
foo(b);
}
Run Code Online (Sandbox Code Playgroud)
编译时,我收到以下链接器错误:
Undefined symbols for architecture x86_64:
"operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Example<A, B, 5, 5> const&)", …Run Code Online (Sandbox Code Playgroud) 以下代码是重现我的问题的最小代码.当我尝试编译,链接器无法找到operator==为Config:
Undefined symbols for architecture x86_64:
"operator==(Config<2> const&, Config<2> const&)", referenced from:
_main in test2.o
Run Code Online (Sandbox Code Playgroud)
该operator==是朋友Config.但是,当我不再声明operator==为朋友时,代码编译器没有错误.
template <int DIM>
class Config{
// comment the following line out and it works
friend bool operator==(const Config<DIM>& a, const Config<DIM>& b);
public:
int val;
};
template <int DIM>
bool operator==(const Config<DIM>& a, const Config<DIM>& b){
return a.val == b.val;
}
int main() {
Config<2> a;
Config<2> b;
a == b;
return 0;
} …Run Code Online (Sandbox Code Playgroud) 这是一个非常简短的片段,不能用g ++ 4.7.1编译(顺便说一下,它不能用gcc 4.6.3编译).
#include <iostream>
template<typename T>
struct Foo
{
template<typename U>
friend std::ostream& operator<<(Foo&, U&);
};
template<typename T, typename U>
std::ostream& operator<<(Foo<T> foo, U& u)
{
std::cout << u;
return std::cout;
}
int main()
{
Foo<int> f;
f << "bar";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这就是gcc 4.7.1输出(4.6.3几乎相同的东西).
/tmp/ccNWJW6X.o:在函数
main': main.cpp:(.text+0x15): undefined reference tostd :: basic_ostream>&operator <<(Foo&,char const(&)[4])'collect2:ld返回1退出状态
有谁能解释为什么?
编辑
我也尝试过clang 3.1,它说的完全一样.
我在学习模板时遇到过以下练习:
#include <iostream>
using namespace std;
template <class T>
class A {
T _v;
public:
A() {}
A(T v) : _v(v) {}
friend ostream & operator<<(ostream & c, const A<T> & v);
};
template <class T>
ostream & operator<<(ostream & c, const A<T> & v){
c << v._v; return c;
}
int main()
{
A<int>a(10);
cout << a << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该代码片段应该在编译期间产生错误,而且确实如此。这是链接器错误,但我无法理解。
我尝试更改几行代码,错误似乎是由模板的安装引起的operator<<,因为删除该模板并编写特定的运算符使代码可以工作。我还感觉模板会被实例化多次,而不仅仅是int.
然而,据我有限的知识,模板定义似乎很好。我缺少什么?
确切的错误(VS 2017)是: Error LNK2019: unresolved external symbol "class std::basic_ostream > …
正如标题所述,我遇到了臭名昭著的unresolved external symbol链接器问题。
我已经移动了.h文件中的所有内容。模板类不再在.h和.cpp文件之间拆分。
我已将它们包含在主文件中。我已经三重四重检查了定义是否存在(显然)。
我的文件如下:
Utils.h:
只是一个漂亮的 coutvector和valarray。测试和工作。
#pragma once
#include <vector>
#include <valarray>
#include <ostream>
using std::vector;
using std::valarray;
using std::ostream;
template <typename ValueType>
ostream& operator<< (ostream&, vector<ValueType>);
template <typename ValueType>
ostream& operator<< (ostream&, valarray<ValueType>);
template <typename ValueType>
ostream& operator<< (ostream& out, vector<ValueType> v)
{
out << "Vec[";
for (int i = 0; i < v.size() - 1; i++)
out << v[i] << ", "; …Run Code Online (Sandbox Code Playgroud)