额外小知识:
实例化:用具体值去代替模版的参数这一行为, 生成一个具体类
template struct Rob<A_f, &A::a>;
特化:由于某种类型的逻辑需要特殊考虑,模版的范型不能描述。所以对这种特殊情况需要单独写一个特例模版。
template<>
struct Rob<A_f, &A::a>;
注意看两者的差别
对于类的私有成员在不修改类代码的情况下,该怎么做呢
方法一:
利用 c++的内存布局,见前面的文章
c++ 内存布局模型
1.1节 pri_short_a 的访问
方法二:
写一个内存布局一模一样的类,然后对应成员的访问级别为 public
方法三:
利用模板 + 友元
#include <iostream>
#include <utility>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>
#include <fstream>
using namespace std;
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;
// 也可以在此声明
//type get(A_f);
};
// 这个函数和实例化的那个函数一, 再次声明声明函数
// 友元函数使用时得再次声明, 可以在全局作用域, 也可以在某个其他类里声明
int A::* get(A_f);
// 实例化内部的友元函数, 这是实例化, 生成一个具体类
template
struct Rob<A_f, &A::a>;
int main() {
A a(42);
std::cout << "proof: " << a.*(get(A_f())) << std::endl;
a.*get(A_f()) = 24;
std::cout << "proof: " << a.*(get(A_f())) << std::endl;
}