为某些模板参数设置public/private on template函数
set public/private on template function for some certain template parameter
是否可以使某个模板函数对某些模板参数具有2个可访问级别?(通过拆分为2个函数?)
class B{
enum ENU{
T0,T1,T2
}
template<ENU T=T0> someType f(){ ... } //want T1,T2 = public, T0 = private
};
当前使用情况(解决方案不应更改):-
B b;
int aa=b.f<T0>(); //should fail
std::string bb=b.f<T1>();// should ok
编辑: B有很多这样的函数
这里是完整的代码(以防有人想编辑或使用)https://ideone.com/ryNCml.
我怀疑你想做的是可能的,因为在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
}
如果您想使用相同的函数实现,您可以将其转发给公共方法,或者简单地将T0
设置为私有。
或者,您可以使用可以转换值的代理对象,尽管我不确定这是标准的c++还是我熟悉的编译器的扩展:
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> {};
}
据我所知,您希望在调用成员方法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>();
}
如果您只想支持有限的模板参数集,我会编写三个不是模板函数的函数,并给它们适当的可见性。然后将它们委托给一个私有模板函数来完成这项工作。这看起来像:
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>(); }
};
与您的要求相反,用法发生了变化——但这通常是最简单的方法:
B b;
int aa=b.fT0(); // fails
int bb=b.fT1();// ok
或者,你可以让模板是公共的,但是给它一个虚拟实参(默认值),并让虚拟实参的类型依赖于模板形参(通过traits)。如果dummy的类型是私有类,则该模板只能由成员调用。
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
注意:后一种解决方案还没有提供给编译器。会有错别字
相关文章:
- 瓦尔格林德:数学函数"Conditional jump or move depends on uninitialised value(s)"
- std::make_shared和protected/private构造函数
- 循环挂起迭代的 std::擦除 on std::list
- SIGSEGV on Boost UDP 套接字关闭 - tcache_get at malloc.c.
- CPP 中的瓦尔格林德和记忆泄漏:"Conditional jump or move depends on uninitialised values"
- std::bind on statd::array 的运算符 []
- 您将如何连接"on the fly"文本+整数并将其传递给函数?
- 如何修复输出日志中的"EnableInput can only be specified on a Pawn for its Controller"错误
- VS2019 - Sudo Remote Debugging on Linux with Cmake project
- C++ library with Tensorflow on Android
- SFML 交叉编译 for Windows on Linux.
- 如何摆脱C++中未解析的外部符号"private: static char"错误?
- How to recover system gcc compiler on centos 6
- Cmake with Flex/Bison on windows
- 按原样保存用户输入 - Ruby on Rails
- OpenAL C++ on Linux
- Boost::process on Windows - with MinGW?
- C++ - "private"单身人士?
- CMake on FindOpenGL.cmake 中的错误,当使用导入的目标 OpenGL::GLU?
- 为某些模板参数设置public/private on template函数