如何将模板类的一个实例与另一个模板

时间:2015-10-25 15:00:09

标签: c++ templates c++14

我有一个模板类,它仅对用户界面函数使用模板参数,并在内部将数据保存在示例中的i等字段中。 i的类型不是模板化的。所有实例化必须协同工作并访问i,但{}不能从模板用户外部访问i。 问题是如何结交同一模板的不同实例。他们必须访问其他实例的私有数据,并且在内部所有这些实例都是一样的。

假设,我想比较模板的不同实例,如下例所示。此处i用于实例化其他模板参数是私有的,如果我尝试声明此模板friend,则它不起作用。 我知道,我可以在类模板之外定义operator ==,但是假设我需要做一些函数,比如is_same,它必须是一个成员,我希望它的主体在课堂宣言。

#include <iostream>

template<typename T>
class C
{
    template<typename U> // ????????
    friend class C;

    template<typename U>
    friend bool operator == (C const& c1, C<U> const& c2) noexcept
    {
      return c1.i == c2.i;
    }

    int i;

  public:

    C(): i {0} {}
    C(int val): i {val} {}

    template<typename U>
    bool is_same(C<U> const& c)
    {
      return c.i == i;
    }

}; // template class C

int main()
{
  C<int>  c1 {5};
  C<char> c2 {5};

  if (c1 == c2) std::cout << "All ok" << std::endl;
  else          std::cout << "Very bad" << std::endl;

  if (c1.is_same(c2)) std::cout << "All ok" << std::endl;
  else                std::cout << "Very bad" << std::endl;

  return 0;
}

编译错误(gcc 5.1 -std = c ++ 14)

~/main.cpp:15:9: error: «int C<char>::i» is private

1 个答案:

答案 0 :(得分:0)

那么为什么这不是用类内部编译的, 并在课外编译。

当你有这个:

  template <typename T> struct C { 
  template<typename U>
  friend bool operator == (C const& c1, C<U> const& c2)
  {
    return c1.i == c2.i;
  }
  };
  C<int>() == C<char>()

::operator==的外部范围内生成了两个class C,在我们的例子中是全局命名空间:::operator==<char>(C<int> const& c1, C<char> const& c2)(1)和 ::operator==<int>(C<char> const& c1, C<int> const& c2)(2),第一个是C<int>的朋友,第二个是朋友C<char>。编译器使用(1)。 (1)只是C<int>的朋友,所以编译时错误。

但是如果你写这样的代码:

template <typename T> struct C { 
    template<typename U1, typename U>
    friend bool operator == (C<U1> const& c1, C<U> const& c2);
private:
    int i;
};

template<typename U1, typename U>
bool operator == (C<U1> const& c1, C<U> const& c2)
{
    return c1.i == c2.i;
}

其中operator==未在C内实现,则编译器不生成operator==超出其已使用的类C的范围, 所以我们::operator==<int, char>这两个类的朋友C<int>C<char>。最后当你有:

template <typename T> struct C { 
    template<typename U1, typename U>
    friend bool operator == (C<U1> const& c1, C<U> const& c2) {
        return c1.i == c2.i;
    }
private:
    int i;
};

C<int>() == C<char>()的情况下,您有两个由::operator== ::operator==<int>(C<int>const&, C<char>const&)的编译器变体生成的 ::operator==<char>(C<int>const&, C<char>const&)和编译器应该在这里生成编译时错误。

参考c ++ 11标准最后草案,第14.5.4和11.3.5节。

相关问题