我有一个非类型类模板(例如Counted),它指向一个类模板的实例(例如Counter)。只要两个模板类都是兄弟姐妹,一切都可以正常工作,例如编写一个打印操作符。
现在有几个原因,我想把Counter里面的Counted作为一个内部类,我发现自己无法写一个打印操作员。
Here's a working "sibling class" version,主要代码在这里:
template < class Count >
struct Counter {
using count_type = Count;
count_type instances = 0;
};
template < class Cnt, Cnt& c>
struct Counted {
using id_type = typename Cnt::count_type;
id_type id;
Counted() : id(c.instances) { ++c.instances; }
~Counted() { --c.instances; }
};
template < class Cnt, Cnt& c >
std::ostream& operator<<(std::ostream& os, Counted<Cnt,c> sib) {
os << "printing sibling " << sib.id;
return os;
}
using SCounter = Counter<std::size_t>;
SCounter sc;
using SCounted = Counted<SCounter, sc>;
Here's the not compiling "inner class" version主要代码在这里:
template < class Count >
struct Counter {
using count_type = Count;
count_type instances = 0;
template <Counter& c>
struct Counted {
using id_type = count_type;
id_type id;
Counted() : id(c.instances) { ++c.instances; }
~Counted() { --c.instances; }
};
};
template < class Count, Counter<Count>& c >
std::ostream& operator<<(std::ostream& os,
typename Counter<Count>::template Counted<c>& sib) {
os << "printing inner " << sib.id;
return os;
}
using SCounter = Counter<std::size_t>;
SCounter sc;
using SCounted = SCounter::Counted<sc>;
错误:
prog.cpp: In function 'int main()':
prog.cpp:32:15: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
std::cout << j << std::endl;
^
In file included from /usr/include/c++/4.9/iostream:39:0,
from prog.cpp:1:
/usr/include/c++/4.9/ostream:602:5: note: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Counter<unsigned int>::Counted<(* & sc)>]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
我的代码,编译器中是否存在问题,或标准是否允许这样做?
答案 0 :(得分:1)
Koenig运营商是您想要的:
template <Counter& c>
struct Counted {
using id_type = count_type;
id_type id;
Counted() : id(c.instances) { ++c.instances; }
~Counted() { --c.instances; }
friend std::ostream& operator<<(
std::ostream& os,
Counted const& sib
) {
os << "printing inner " << sib.id;
return os;
}
};
};
这里我们创建一个friend operator<<
。当您尝试将<<
与Counted
实例一起使用时,将通过ADL(或Koenig查找)找到它。
为每种类型的Counted
创建了一个不同的函数,并且没有完成模板推导。