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

4

我有一个模板类MyClass

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

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

  1. Compiler doesn't report error.

    template <class T>
    void f()
    {
      MyClass<int> a;
      a.PrivateFunction();
    }
    
  2. Compiler reports error.

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

你调用过模板函数 f() 了吗? - billz
只有在那种情况下我才会收到错误,但我很想知道为什么在调用函数之前我看不到错误。 - Ashot Khachatryan
1
无论你使用哪个编译器,都会出现错误。即使 f 从未实例化,clang 对于 1 和 2 都会显示错误。 - user743382
在1中无法生成有效的f()模板实例化,因此该模板是不良形式的,无需诊断。编译器是否在模板定义时间或实例化时间诊断错误是实现质量问题。 - T.C.
这里有一个很酷的视频系列,Mr. STL讲解了许多关于Core C++(以及其他)的工作原理:Core C++。如果你正在开始你的[标签:语言律师]职业生涯,那么值得一看! - Ivan Aksamentov - Drop
1个回答

13
为什么我可以从模板函数中使用私有方法?
你不能。根据§14.6 [temp.res]/p4:
如果无法生成有效的模板特化,并且该模板未被实例化,则该模板是非法的,不需要进行诊断。
我很感兴趣为什么在调用函数之前看不到错误。
编译器可能会推迟分析,直到函数模板被实例化。但是,这是一种实现定义的行为,你的代码仍然是不合法的(参见 §14.6/p4 的续篇):
“如果模板被实例化,将根据本标准中的其他规则诊断错误。这些错误何时被诊断是实现质量问题。” GCC demo(只在实例化时发出错误)
Clang demo(在没有实例化的情况下发出错误)

1
这并不是非常准确的。模板形式不正确,不需要进行诊断,因此编译器可以自由地进行诊断。它是否这样做是实现质量问题,至少有一个编译器(Clang)在不需要实例化f()的情况下就会诊断错误。 - T.C.
在这里,苛求细节是有帮助的:不存在所谓的模板函数。有函数模板可以用来生成函数。如果一个函数模板生成了一个不合规范的函数,那么该特定函数将报告一个错误。判断一个函数模板是否只能生成不合规范的函数更加困难,甚至可以说这不是一个错误。 - nwp
这个诊断不是必需的,因为很难指定哪些问题足够明显,可以在实例化之前进行诊断。例如,private方法可以被友元调用,这意味着您需要在没有实际实例化的情况下确定函数模板实例化是否是一个友元。 - MSalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接