打印非类型模板内部类

时间:2015-05-21 12:01:41

标签: c++ c++11 type-inference

我有一个非类型类模板(例如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)
     ^

我的代码,编译器中是否存在问题,或标准是否允许这样做?

1 个答案:

答案 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创建了一个不同的函数,并且没有完成模板推导。