【问题标题】:Cannot access private member from a template friend function [closed]无法从模板朋友功能访问私人成员[关闭]
【发布时间】:2017-11-20 16:03:40
【问题描述】:

这是我的代码示例:

#include <iostream>
#include <memory>

class Base
{
public:
  virtual void name() = 0;
};

using ptr_t = std::unique_ptr<Base>;

class A : public Base
{
  A(int x) : n(x) {}

public:
  void name() override
  {
    std::cout << "Test " << n << "\n";
  }

  template <typename T>
  friend ptr_t create(int x);

private:
  int n;
};

template <typename T>
ptr_t create(int x)
{
  return std::make_unique<T>(x);
}

int main()
{
  auto a = create<A>(3);
  a->name();
}

起初我以为问题出在从std::unique_ptr&lt;A&gt;std::unique_ptr&lt;Base&gt; 的转换上。但这似乎在一个孤立的代码示例中工作正常,并且根据这个答案也是正确的: unique_ptr to a base class

如果我使用原始指针而不是唯一指针,上面的代码也可以工作。

有人可以解释我缺少什么。谢谢。

【问题讨论】:

  • 再次查看函数声明的签名。 :)
  • 对于发布不完整的代码示例,我深表歉意。我已经更新了代码示例并改进了问题的描述。请重新打开问题@Rakete1111
  • 我愿意,但您的代码似乎是 compiles just fine...
  • 嗯,这很有趣。我正在使用 MSVC 15.0 编译器(Visual Studio 2017)。我得到与这个在线编译器相同的错误rextester.com/YXPKUO5666
  • 可能是后来修复的编译器错误。 goldbolt 使用 19.10.25017,而你的使用稍旧的,它编译得很好for me

标签: c++ oop templates c++14


【解决方案1】:

小心,你的朋友函数的签名需要匹配它的实现:

class A
{
  A() {}

  template <typename T>
  friend T* create();
};

template <typename T>
T* create()
{
    return new T;
}

int main()
{
    auto a = create<A>();
}

更新到您的新问题。你需要给make_unique加好友,它是访问构造函数的函数。但是为什么需要模板?这对我有用:

#include <iostream>
#include <memory>

class Base
{
public:
  virtual void name() = 0;
};


class A final : public Base
{
  A(int x) : n(x) {}

public:
  void name() override
  {
    std::cout << "Test :" << n << "\n";
  }

  friend std::unique_ptr<A> std::make_unique<A>(int& x);

private:
  int n;
};

std::unique_ptr<A> create(int x)
{
  return std::make_unique<A>(x);
}

int main()
{
  auto a = create(3);
  a->name();

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多