编辑:序言:我是我自己的无知以及深夜编码的受害者。
我正在使用模板模板编写模板化类。它有一个迭代器,这意味着我需要提供一个适当模板的operator==()
。这是我遇到麻烦的地方。
代表性代码示例如下:
#include <iostream>
#include <typeinfo>
using namespace std;
namespace detail {
template <typename T> class foo {};
template <typename T> class bar {};
}
template <template<class> class A, template<class> class B>
struct basic_thing {
template <typename T> using target_type = A<B<T>>;
target_type<float> fmember;
target_type<int> imember;
struct iterator {
bool equal (const iterator& other) { return true; }
};
iterator begin () { return iterator{}; }
iterator end () { return iterator{}; }
};
template <template<class> class A, template<class> class B>
bool operator== (const typename basic_thing<A, B>::iterator& lhs, const typename basic_thing<A, B>::iterator& rhs) {
return lhs.equal(rhs);
}
int main ()
{
using Thing = basic_thing<detail::foo, detail::bar>;
Thing t;
cout << typeid(t.fmember).name() << endl;
cout << typeid(t.imember).name() << endl;
bool b = (t.begin() == t.end());
return 0;
}
我在这里的目标是提供一种定义basic_thing::target_type
的可组合方式,并且该模式可用于该目的。但是,我一直坚持如何为operator==()
声明basic_thing::iterator
。这不是很简单,或者我显然缺少了一些东西。 (就像后者一样。)
-std=c++11
的g ++-7.4.0产生以下内容:
foo.cc: In function 'int main()':
foo.cc:39:23: error: no match for 'operator==' (operand types are 'basic_thing<detail::foo, detail::bar>::iterator' and 'basic_thing<detail::foo, detail::bar>::iterator')
bool b = (t.begin() == t.end());
~~~~~~~~~~^~~~~~~~~~
foo.cc:27:6: note: candidate: template<template<class> class A, template<class> class B> bool operator==(const typename basic_thing<A, B>::iterator&, const typename basic_thing<A, B>::iterator&)
bool operator== (const typename basic_thing<A, B>::iterator& lhs, const typename basic_thing<A, B>::iterator& rhs) {
^~~~~~~~
foo.cc:27:6: note: template argument deduction/substitution failed:
foo.cc:39:32: note: couldn't deduce template parameter 'template<class> class A'
bool b = (t.begin() == t.end());
^
执行此操作的正确方法是什么?涉及模板模板,甚至有可能吗?
答案 0 :(得分:5)
更简单的方法是直接在struct内部创建它(作为成员或朋友函数):
template <template<class> class A, template<class> class B>
struct basic_thing {
// ...
struct iterator {
bool equal (const iterator& other) { return true; }
bool operator ==(const iterator& rhs) const;
// friend bool operator ==(const iterator& lhs, const iterator& rhs);
};
};
使用
template <template<class> class A, template<class> class B>
bool operator== (const typename basic_thing<A, B>::iterator& lhs,
const typename basic_thing<A, B>::iterator& rhs);
A
和B
是不可推论的(在::
的左侧)。
所以只能用丑陋的方式来称呼:
bool b = operator==<detail::foo, detail::bar>(t.begin(), t.begin());