nig*_*arc 6 c++ operator-overloading
让我受到欢迎,我遇到了一些问题.我有一个std::vector包含一些自己的类的typedef'ed :
typedef std::vector<data::WayPoint> TWayPointList;
Run Code Online (Sandbox Code Playgroud)
这是结构内部的嵌套类型,DataHandler它在某些命名空间中存在data.
所以,现在我想打印出矢量的单个内容.为此,我的想法是重载<<运算符并循环遍历typedef'ed向量的单个元素.所以我在结构中声明了以下输出操作符DataHandler:
namespace data
{
structure DataHandler
{
// ... some code
typedef std::vector<data::WayPoint> TWayPointList;
// ... some more code
/**
* @brief Globally overloaded output operator
*
* @param[in] arOutputStream Reference to output stream.
* @param[in] arWayPointList WayPoint which should be printed to output stream.
*/
LIB_EXPORTS friend std::ostream& operator<<(std::ostream& arOutputStream, const data::DataHandler::TWayPointList& arWayPointList);
} // structure DataHandler
} // namespace data
Run Code Online (Sandbox Code Playgroud)
并在相应的源文件中定义它:
namespace data
{
std::ostream& operator<<(std::ostream& arOutputStream, const DataHandler::TWayPointList& arWayPointList)
{
for(DataHandler::TWayPointList::const_iterator lIterator = arWayPointList.begin(); lIterator < arWayPointList.end(); ++lIterator)
{
arOutputStream << *lIterator << std::endl;
}
return arOutputStream;
}
} // namespace data
Run Code Online (Sandbox Code Playgroud)
编译好了.但是,如果我添加这样的东西
int main(int argc, char *argv[])
{
// create Waypoint
data::WayPoint lWayPoint;
// create waypoint list
data::DataHandler::TWayPointList lWayPointList;
// append two elements
lWayPointList.push_back(lWayPoint);
lWayPointList.push_back(lWayPoint);
std::cout << lWayPointList << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在我testmain.cpp的编译器中提到,它找不到正确的operator<<(并做了很多假设,它找到了哪一个......包括我自己在其他类中定义的一些).像这样的一些错误
src/main.cpp:107: error: no match for 'operator<<' in 'std::cout << lWayPointList'
src/main.cpp:107:18: note: candidates are:
... a long list of canditates...
Run Code Online (Sandbox Code Playgroud)
我认为它与ADL有关,但我没有明白这一点.
那么,任何想法和想法让代码工作?
[edit]我在源代码和错误输出中添加了一些文件以便澄清.
friend声明在具有此类friend声明的类的名称空间中声明了名称空间级别的函数.从运算符的定义来看,你似乎是在全局命名空间中定义它(顺便提一下你在朋友声明中的评论所说的,太糟糕的编译器不会读取注释).您需要operator<<在正确的命名空间中定义:
std::ostream& mkilib::operator<<(std::ostream& arOutputStream,
/*^^^^^^^^*/ const mkilib::DataHandler::TWayPointList& arWayPointList)
Run Code Online (Sandbox Code Playgroud)
或者:
namespace mkilib {
std::ostream& operator<<(std::ostream& arOutputStream,
const DataHandler::TWayPointList& arWayPointList) {...}
}
Run Code Online (Sandbox Code Playgroud)
在你的程序中有两个operator<<声明采用了TWayPointList对象,一个在全局命名空间中(定义是一个自我声明)和一个在::mkilib命名空间中(来自友元声明).依赖于参数的查找是找到的::mkilib,但是从未在代码中定义过.
在更新之后,似乎这不是真正的问题,因为编译器无法找到重载(上面的答案是关于编译但未链接的代码).有些内容已经从代码更改为您对命名空间的要求.如果Waypoint和operator<<那个std::vector<Waypoint>在同一名称空间中定义了,那么ADL将找到正确的重载.请注意,DataHandler定义的命名空间没有任何效果.
实际上,现在我考虑一下,原来的答案确实适用.友元声明对查找没有任何影响,因为ADL不会查找内部DataHandler搜索该运算符,因此唯一的声明operator<<是定义中的自声明.
请注意,友元声明在名称空间级别声明实体,但声明仅在具有friend声明的类中可见.
建议:避免使用指令,它们只会带来混乱和痛苦.如果需要,重新打开命名空间或限定标识符...使用指令使查找的推理更加复杂.
| 归档时间: |
|
| 查看次数: |
1629 次 |
| 最近记录: |