是否可以使某个模板功能对某些模板参数具有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。
答案 0 :(得分:2)
我怀疑你想要做什么是可能的,因为在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> {};
}
答案 1 :(得分:2)
据我所知,您希望在调用成员方法var dFormat = "dd/MM/yyyy h:mm:ss tt";
时禁止使用T0
作为模板参数。
为此,您可以使用f
或std::enable_if
它遵循一个最小的工作示例:
static_assert
答案 2 :(得分:0)
鉴于您只想支持一组有限的模板参数,我会编写三个不是模板函数的函数,并为它们提供正确的可见性。然后让它们委托给一个完成工作的私有模板函数。这看起来像是:
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
或者,您可以将模板设为公共,但为其提供一个伪参数(使用默认值),并使伪参数的类型取决于模板参数(通过特征)。如果虚拟类型是私有类,则模板只能由成员调用。
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
注意:后一种解决方案尚未提供给编译器。会有错别字。