这是经典的'passkey‘模式,它只允许在特定类的范围内访问函数:
#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>有什么办法让你做那件事吗?
发布于 2021-06-29 18:30:57
令我惊讶的是,你的各种模板竟然与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调用它。
https://stackoverflow.com/questions/68180206
复制相似问题