【问题标题】:Why I can use private methods from template functions为什么我可以使用模板函数中的私有方法
【发布时间】:2014-11-07 11:08:45
【问题描述】:

我有模板类 MyClass

template <class T>
class MyClass
{
public:
  MyClass() { }
private:
  void PrivateFunction() { 
    std::cout << "Message From Private Function" << std::endl; 
  }
};

现在当我尝试在另一个函数编译器中使用 PrivateFunction() 时会报告错误,但是当我在模板函数中尝试相同的编译器时不会显示任何错误。

  1. 编译器不报错。

    template <class T>
    void f()
    {
      MyClass<int> a;
      a.PrivateFunction();
    }
    
  2. 编译器报错。

    void f()
    {
      MyClass<int> a;
      a.PrivateFunction();
    }
    

【问题讨论】:

  • 你调用模板函数f()了吗?
  • 是的,只有在这种情况下我才会收到错误,但我很感兴趣为什么在调用函数之前看不到错误。
  • 是否出现错误取决于编译器。即使 f 从未实例化,clang 也会显示 1 和 2 的错误。
  • 无法为1中的模板f()生成有效的实例化,因此模板格式错误,无需诊断。编译器在模板定义时还是在实例化时诊断错误是实现质量问题。
  • 这是一个很酷的视频系列,STL 先生讲述了这些(以及许多其他)事情是如何工作的:Core C++。如果您正在开始您的language-lawyer 职业生涯,那么值得一看!

标签: c++ function class templates


【解决方案1】:

为什么我可以使用模板函数中的私有方法?

你不能。 §14.6 [temp.res]/p4:

如果无法为模板生成有效的特化,并且该模板未实例化,则模板格式错误,无需诊断。


我很感兴趣为什么在调用函数之前看不到错误

编译器可能会推迟分析,直到函数模板被实例化。尽管如此,这是一个实现定义的行为,并且您的代码仍然格式错误(§14.6/p4 的延续):

[ 注意:如果模板被实例化,错误将根据本标准中的其他规则进行诊断。 准确诊断出这些错误是实施质量问题。 — 尾注 ]

GCC demo(仅在实例化时发出错误)
Clang demo(在未实例化时发出错误)

【讨论】:

  • 这不是很准确。该模板格式不正确,不需要诊断,因此编译器可以根据需要自行诊断。是否这样做是实现的质量问题,并且至少有一个编译器 (Clang) 可以在不需要实例化 f() 的情况下诊断错误。
  • 学究式在这里有帮助:没有模板函数之类的东西。有可用于生成函数的函数模板。如果函数模板生成格式错误的函数,则特定函数会报告错误。判断一个函数模板是否只能生成格式错误的函数更加困难,如果这甚至是一个错误也是值得商榷的。
  • 此诊断不是必需的,因为很难指定哪些问题足够明显,无需实例化即可诊断。例如。 private 方法可以被朋友调用,这意味着您需要弄清楚 - 无需实际实例化 - 函数模板实例化是否会成为朋友。
猜你喜欢
  • 2012-01-26
  • 2012-05-01
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
  • 2014-10-29
  • 1970-01-01
相关资源
最近更新 更多