c++ - 模板类的密钥模式,朋友和模板模板参数的问题
问题描述
这是经典的“密码”模式,它只允许在特定类的范围内访问函数:
#include <iostream>
template <typename T>
class passkey {
private:
friend T;
passkey() {}
// noncopyable
passkey(const passkey&) = delete;
passkey& operator=(const passkey&) = delete;
};
struct A {
A();
};
void g(int i, passkey<A>) {
std::cout << i;
}
A::A(){g(42,{});}
int main() {
A a;
return 0;
}
这里的函数g
只能在内部调用A
。但是如果A
现在是模板类,是否可以扩展它?以下代码段无法编译(使用clang,但可以使用gcc ...),因为对于模板朋友来说,似乎必须使用详细说明符,这似乎会导致声明冲突......
#include <iostream>
template <template<typename...> class T>
class passkey {
private:
template<typename...> friend class T;
passkey() {}
// noncopyable
passkey(const passkey&) = delete;
passkey& operator=(const passkey&) = delete;
};
template<typename T>
struct A {
A();
};
void g(int i, passkey<A>) {
std::cout << i;
}
template<typename T>
A<T>::A(){g(42,{});}
int main() {
A<void> a;
return 0;
}
这给出了铿锵声:
>source>:6:38: error: declaration of 'T' shadows template parameter
template<typename...> friend class T;
^
<source>:3:39: note: template parameter is declared here
template <template<typename...> class T>
有什么诀窍可以完成这项工作吗?
解决方案
我很惊讶你的可变参数模板实际上是用 GCC 编译的。这就是我实际写它的方式:
template <template<typename... Ts> class T, typename... Ts>
class passkey {
private:
friend class T<Ts...>;
constexpr passkey() {
return;
}
passkey(passkey const&) = delete;
passkey& operator=(passkey const&) = delete;
};
此外,我会让函数g
获取 r 值引用并std::move
显式调用它。
推荐阅读
- typescript - 用有效负载错误反应本机'NAVIGATE'
- java - 重试失败的服务调用,但使用不同的实现
- python - 查找一维 numpy 数组中的岛数
- azure - 试图将我的 Azure.Storage.Blobs 上传代码转换为新的 nuget 12.10,但无法弄清楚。在 12.8 中看起来要简单得多
- wordpress - 如何切换主题并仍然能够显示保持相同的内容?
- python - pip install 模块,但具有依赖的修复版本
- ruby-on-rails - 如何在一张表中创建两个外键?
- reactjs - 如何在反应中添加具有动态路由的令牌?
- multithreading - 创建线程并使用 Tcl 并行执行过程
- node.js - Typegoose / Mongoose 将自定义类型映射到 db