C++ 为某个模板参数设置模板上的public/private函数
是否可以使某个模板函数对某个模板参数具有2个可访问性级别?(通过拆分为2个功能?)C++ 为某个模板参数设置模板上的public/private函数,c++,templates,C++,Templates,是否可以使某个模板函数对某个模板参数具有2个可访问性级别?(通过拆分为2个功能?) B类{ 枚举菜单{ T0,T1,T2 } 模板someType f(){…}//want T1,T2=public,T0=private }; 当前使用情况(解决方案不应更改):- B; int aa=b.f()//应该失败 std::string bb=b.f();//应该可以 编辑:B有很多类似的功能 这是完整的代码(以防有人想要编辑或使用)。如果您只想支持有限的模板参数集,我将编写三个不是模板函数的
B类{
枚举菜单{
T0,T1,T2
}
模板someType f(){…}//want T1,T2=public,T0=private
};
当前使用情况(解决方案不应更改):-
B;
int aa=b.f()//应该失败
std::string bb=b.f();//应该可以
编辑:B有很多类似的功能
这是完整的代码(以防有人想要编辑或使用)。如果您只想支持有限的模板参数集,我将编写三个不是模板函数的函数,并为它们提供正确的可见性。然后让他们委托一个私有模板函数来完成这项工作。这看起来像:
class B{
public:
enum ENU{
T0,T1,T2
}
private:
template<ENU T=T0> int f(){
std::cout<<"In enum "<<T<<std::endl;
return 0;
}
protected:
someType fT0() { return f<T0>(); }
public:
someType fT1() { return f<T1>(); }
someType fT2() { return f<T2>(); }
};
或者,您可以将模板设置为公共模板,但为其提供一个伪参数(使用默认值),并使伪参数的类型取决于模板参数(通过traits)。如果虚拟对象的类型是私有类,则模板只能由成员调用
template <ENU T>
struct protection_traits;
class B{
friend class protection_traits<T0>; // So it has access to Protected.
protected:
struct Protected{};
public:
struct Public{};
enum ENU{
T0,T1,T2
}
template<ENU T=T0> int f( typename protection_traits<T>::type = {})
{ std::cout<<"In enum "<<T<<std::endl; }
};
template <ENU T>
struct protection_traits
{
typedef B::Public type; // Default to public
};
template<>
struct protection_traits<T0>
{
typedef B::Protected type; // But T0 uses Protected
};
模板
结构保护特性;
B类{
friend class protection_traits;//因此它可以访问受保护的。
受保护的:
结构保护{};
公众:
结构公共{};
枚举菜单{
T0,T1,T2
}
模板intf(类型名保护特征::类型={})
{STD::Couth我怀疑你想做的是可能的,因为C++中不允许有一个值上的专门函数。
如果不需要枚举,可以编写类似的代码:
class B {
public:
struct T0{};
struct T1{};
struct T2{};
template<typename T> void f(T, ...) {
static_assert(std::is_same_v<T, T1> || std::is_same_v<T, T2>);
}
private:
void f(T0, ...) {}
};
int main(int argc, char **argv) {
B b{};
b.f(T1{}); // Should compile
b.f(T0{}); // Should not compile
}
据我所知,您希望禁止在调用成员方法f
时使用T0
作为模板参数
为此,您可以使用std::enable_if
或static_assert
下面是一个简单的工作示例:
#include<type_traits>
class B {
public:
enum ENU { T0,T1,T2 };
template<ENU T>
std::enable_if_t<(T==T1||T==T2),int>
f() { return 42; }
template<ENU T>
int g(){
static_assert(T==T1||T==T2, "not allowed");
return 42;
}
};
int main() {
B b;
b.f<B::T1>();
// It doesn't work
//b.f<B::T0>();
b.g<B::T1>();
// It doesn't work
//b.g<B::T0>();
}
#包括
B类{
公众:
枚举ENU{T0,T1,T2};
模板
std::如果启用,则启用
f(){return 42;}
模板
int g(){
静态断言(T==T1 | | T==T2,“不允许”);
返回42;
}
};
int main(){
B B;
b、 f();
//它不起作用
//b、 f();
b、 g();
//它不起作用
//b、 g();
}
Cool!我仍在努力管理成员模板函数专用化。我测试,它可以工作…但不像模板那样可爱,…谢谢!(投票表决)我在“使伪参数的类型取决于模板参数(通过特征)”方面迷失了方向,你能编辑我的完整代码吗(我编辑了问题)或者提供一些示例?他的意思是他希望您将使类唯一的某个特性作为参数传递。例如,如果您有一个car类,并且希望使其唯一,请将其创建一个接口“IIndentifier”,并将其用作模板模式(伪参数将获得一个IIdentifier作为其对象)是的……我可以解释,但只能含糊其辞(这有助于模板推断)不知道如何转换成代码……我只是C++的初学者……是什么?图式?那些是什么?都让我困惑……你能查一下完整的代码吗?我想我已经使用过那个技术了。那个接口是一个特性——它本身是一个模板,可以传递给原来的模板。你可以在网上搜索它的模板模板。它的
template <ENU T>
struct protection_traits;
class B{
friend class protection_traits<T0>; // So it has access to Protected.
protected:
struct Protected{};
public:
struct Public{};
enum ENU{
T0,T1,T2
}
template<ENU T=T0> int f( typename protection_traits<T>::type = {})
{ std::cout<<"In enum "<<T<<std::endl; }
};
template <ENU T>
struct protection_traits
{
typedef B::Public type; // Default to public
};
template<>
struct protection_traits<T0>
{
typedef B::Protected type; // But T0 uses Protected
};
B b;
int aa=b.f<T0>(); // fails (no access to B::Protected)
int bb=b.f<T1>(); // ok
class B {
public:
struct T0{};
struct T1{};
struct T2{};
template<typename T> void f(T, ...) {
static_assert(std::is_same_v<T, T1> || std::is_same_v<T, T2>);
}
private:
void f(T0, ...) {}
};
int main(int argc, char **argv) {
B b{};
b.f(T1{}); // Should compile
b.f(T0{}); // Should not compile
}
class B {
public:
enum class T { //< Strong typed!
T0,
T1,
T2
}
template <T t>
struct TWrapper {};
template <T ActualT>
void f(..., TWrapper<ActualT> tw = TWrapper<ActualT>{});
private:
template <>
struct TWrapper<T0> {};
}
#include<type_traits>
class B {
public:
enum ENU { T0,T1,T2 };
template<ENU T>
std::enable_if_t<(T==T1||T==T2),int>
f() { return 42; }
template<ENU T>
int g(){
static_assert(T==T1||T==T2, "not allowed");
return 42;
}
};
int main() {
B b;
b.f<B::T1>();
// It doesn't work
//b.f<B::T0>();
b.g<B::T1>();
// It doesn't work
//b.g<B::T0>();
}