【发布时间】:2018-04-06 07:38:30
【问题描述】:
我正在尝试将 iostream 运算符实现为可变参数类模板的友元函数。
#include <utility>
#include <iostream>
template<typename... Args>
class StudentInformation {
public:
//friend class Student;
using Members = std::tuple<Args...>;
Members members;
const size_t numArgs{ sizeof...(Args) };
StudentInformation( Args&&... args ) : members{ std::make_tuple<Args...>( std::move( args )... ) } {}
const StudentInformation<Args...>& operator() ( Args... args ) {
members = std::make_tuple<Args>( std::forward<Args>( args )... );
return *this;
}
const StudentInformation<Args...> operator() ( Args... args ) const {
members = std::make_tuple<Args>( std::forward<Args>( args )... );
return *this;
}
friend std::ostream& operator<< ( std::ostream& out, const StudentInformation& c );
friend std::istream& operator>> ( std::istream& in, StudentInformation& c );
};
template<typename... T>
std::ostream& operator<<( std::ostream& out, const StudentInformation<T...>& c ) {
const size_t numArgs = c.numArgs;
for( size_t idx = 0; idx < numArgs; idx++ )
out << std::get<idx>( c.members ) << " ";
return out;
}
template<typename... T>
std::istream& operator>>( std::istream& in, StudentInformation<T...>& c ) {
const size_t numArgs = c.numArgs;
for( size_t idx = 0; idx < numArgs; idx++ )
in >> std::get<idx>( c.members );
return in;
}
由于某种原因,我仍然收到链接器错误。即使在标头中定义了重载,我仍然会收到链接器错误,就好像它们是在 cpp 文件中定义的一样。有什么想法吗?
即使我尝试这种方法:首先声明类的原型,然后声明重载运算符的原型,然后声明类,然后定义友元重载运算符:
#include <utility>
#include <iostream>
template<typename... Args>
class StudentInfo;
template<typename... Args>
std::ostream& operator<<( std::ostream& out, const StudentInfo<Args...>& c );
template<typename... Args>
std::istream& operator>>( std::istream& in, StudentInfo<Args...>& c );
template<typename... Args>
class StudentInfo {
public:
//friend class Student;
using Members = std::tuple<Args...>;
Members members;
const size_t numArgs{ sizeof...(Args) };
StudentInfo( Args&&... args ) : members{ std::make_tuple<Args...>( std::move( args )... ) } {}
const StudentInfo<Args...>& operator() ( Args... args ) {
members = std::make_tuple<Args>( std::forward<Args>( args )... );
return *this;
}
const StudentInfo<Args...> operator() ( Args... args ) const {
members = std::make_tuple<Args>( std::forward<Args>( args )... );
return *this;
}
friend std::ostream& operator<< ( std::ostream& out, const StudentInfo& c );
friend std::istream& operator>> ( std::istream& in, StudentInfo& c );
};
template<typename... T>
std::ostream& operator<<( std::ostream& out, const StudentInfo<T...>& c ) {
const size_t numArgs = c.numArgs;
for( size_t idx = 0; idx < numArgs; idx++ )
out << std::get<idx>( c.members ) << " ";
return out;
}
template<typename... T>
std::istream& operator>>( std::istream& in, StudentInfo<T...>& c ) {
const size_t numArgs = c.numArgs;
for( size_t idx = 0; idx < numArgs; idx++ )
in >> std::get<idx>( c.members );
return in;
}
我仍然收到链接器错误。我可以让这些成为课堂的一部分;但我不想要这种行为。我希望它们在课堂之外定义。按照目前的情况;现在类中的所有内容都是公开的,仅用于测试,但一旦该类按预期工作;其中的所有内容都是私有的,因为这个类将成为另一个类的朋友;拥有类将可以访问其所有私有信息。我不知道如何绕过或解决此链接器错误问题。
1>main.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class StudentInfo<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::vector<int,class std::allocator<int> > > const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$StudentInfo@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@HV12@V?$vector@HV?$allocator@H@std@@@2@@@@Z) referenced in function _main
【问题讨论】:
-
我在几天前发布了此内容,但没有机会查看我发布的内容。当我们要去探望家人周末时,我很着急。我说过我在 cpp 文件中定义了运算符,但实际上我将它们放在包含在头文件底部的内联文件中。
-
我对我的原始问题进行了一些编辑,以更具体地说明为什么它不是重复的,希望能解决我遇到的链接器错误。
标签: operator-overloading variadic-templates iostream c++17 friend