调用模板化成员函数:帮助我理解另一个 *** 帖子中的代码片段

Posted

技术标签:

【中文标题】调用模板化成员函数:帮助我理解另一个 *** 帖子中的代码片段【英文标题】:Calling a templatized member function: Help me understand a code snippet from another *** posting 【发布时间】:2012-04-12 05:22:06 【问题描述】:

参考May pointer to members circumvent the access level of a member?,我想了解一下那个问题中的代码sn-p。

我将代码sn-p粘贴在这里。

#include <iostream>

template<typename Tag, typename Tag::type M>
struct Rob  
  friend typename Tag::type get(Tag) 
    return M;
  
;

// use
struct A 
  A(int a):a(a)  
private:
  int a;
;

// tag used to access A::a
struct A_f  
  typedef int A::*type;
  friend type get(A_f);
;

template struct Rob<A_f, &A::a>;

int main() 
  A a(42);
  std::cout << "proof: " << a.*get(A_f()) << std::endl;

在几个问题中,我在这里强调一个可能会破解其余问题的问题。

main函数中的以下语句我看不懂:

a.*get(A_f())

确实了解(我认为)get(A_F()) 返回指向a.a 的指针。但是,我不明白get() 函数。这实际上是在什么结构中定义的?它是如何在该结构中访问的?

如果上述问题得到回答,我有两个次要问题可能会得到回答,但我会将它们放在这里。首先,在Rob 的定义中,friend 关键字被用于定义和声明的函数get 前面。我以为friend关键字只能用在函数声明前面,表示定义的函数elsewhere可以访问类的私有/受保护成员.谁能解释一下?

第二,我看不懂template struct Rob&lt;A_f, &amp;A::a&gt;;这行。我不明白在没有&lt;...&gt; 的情况下使用template 关键字,我不明白为什么没有模板定义——这似乎是某种前向声明。有人可以解释吗?谢谢。

【问题讨论】:

【参考方案1】:

但是,我不明白get() 函数。这实际上是在什么结构中定义的?它是如何在该结构中访问的?

第一件事:函数get()ARob 类模板的朋友。它不是任何类的成员函数。它是一个免费的功能。

现在,这个 free 函数到底是在哪里定义的?嗯,它在Rob类模板中定义,同时它被声明为friendRob类模板。

我认为friend关键字只能用在函数声明的前面,表示在别处定义的函数可以访问类的私有/受保护成员。谁能解释一下?

是的,它可以声明为一个类的friend,而无需在类中定义它。它可以在一个类中定义,同时可以声明为该类的friend。在您的情况下,它实际上是在类本身中定义的。

其次,template struct Rob&lt;A_f, &amp;A::a&gt;;这行我看不懂。

这被称为具有给定模板参数的类模板的explicit instantiation。您可以在此处看到许多其他显式实例化模板的语法(如果它是函数模板):

C++ Template Specialization and Instantiation Syntax

【讨论】:

谢谢。我仔细查看了您提供的链接和嵌套链接。我接近理解这一点。你能告诉我你是如何从语法中知道template struct Rob&lt;A_f, &amp;A::a&gt;; 是一个实例化,而不是模板特化的声明吗? @DanNissenbaum:因为我知道模板专业化和模板显式实例化的语法。它们的语法不一样;它们是不同的,所以我知道哪个是哪个。 Nawaz - 一个彻底粗鲁的回应。 @DanNissenbaum:这并不粗鲁。如果这很粗鲁,那么可以这样说:你怎么知道int i; 是变量i 的声明?或者说,你怎么知道i 是语法int i; 中的一个变量,你怎么知道i 不是一个函数?请回答我的问题:-) @DanNissenbaum:显式特化以template&lt;&gt; 开头,显式实例化仅以template 开头。

以上是关于调用模板化成员函数:帮助我理解另一个 *** 帖子中的代码片段的主要内容,如果未能解决你的问题,请参考以下文章

std::async 与共享指针模板化成员函数

为啥我不能从 gcc 中的前身模板化成员函数访问祖先方法?

模板化类的模板化成员方法可以在类定义之外定义吗

如何从模板类型中获取指向模板化成员函数的指针?

使用模板化成员函数显式实例化模板类

在类向量中线程化成员函数