【发布时间】:2017-01-11 20:20:20
【问题描述】:
在下面的代码中,我想为我想要使用的特定类型定义实现二元运算符链接的效果 - 对于普通运算符链接,二元运算符返回相同类型的对象,大多数情况只是简单地返回*this,可以轻松地再次用于链接下一个相同类型的对象。
但是,在我的例子中,二元运算符将两个相同类型对象 (awaitable<T>::ref) 的两个 reference_wrappers 作为输入,并返回一个类型为 (awaitable<awaitable<T>::ref>) 的聚合对象,我想使用返回的聚合对象链接下一个 awaitable<T>::ref 并再次返回 awaitable<awaitable<T>::ref> 类型的进一步聚合对象 - 请注意,无论发生多少链接,返回的对象始终是 awaitable<awaitable<T>::ref> 的同一类型。
在位置 (XXX) 定义模板模板参数的友元运算符希望达到此目的,但编译器似乎不愿意执行绑定。
任何人都可以阐明我如何实现所描述的结果吗?
谢谢!
#include <functional>
template <typename T>
struct awaitable
{
typedef std::reference_wrapper<awaitable> ref;
// (A) - okay
friend awaitable<ref> operator||(ref a1, ref a2)
{
awaitable<ref> r;
return r;
}
// (XXX) - this doesn't bind
template < template <typename> class _awaitable >
friend awaitable<ref> operator||(typename awaitable<typename _awaitable<T>::ref>::ref a1, ref a2)
{
awaitable<ref> r;
return r;
}
};
int main(int argc, const char * argv[])
{
awaitable<void> a1;
awaitable<void> a2;
auto r1 = a1 || a2; // Okay - r1 is of type awaitable<awaitable<void>::ref>
awaitable<void> a3;
auto r3 = r1 || a3; // doesn't bind to the operator defined at XXX
return 0;
}
[编辑]-
this 帖子和this 中的答案似乎很好地解释了这种情况,但在我的情况下,朋友运算符有一个模板模板参数(需要它来避免递归模板实例化),这可能会阻止编译器模板实例化时生成正确的命名空间作用域函数?
【问题讨论】:
-
抱歉编辑,我试图简化代码并尽可能消除任何可能的混淆,希望上面的代码应该非常易于阅读(根本不需要向下滚动!)跨度>
-
注意:输入的对象都是reference_wrapper包装的,我特别不希望发生复制,而在实际代码中,复制构造函数被删除了
标签: c++11 templates operator-overloading c++14 overload-resolution