我正在尝试创建一个默认情况下是显式的转换运算符,除了某些指定的类。
更准确地说,我有一个相对简单的类模板,其实例应可转换为其他类型(为简单起见,在整个问题中{int
)。但是,我希望此转换在默认情况下是显式的,但仍允许对另一个类(即作为模板参数传递的类)隐式转换。如果没有最后一部分,它将是这样:
template<typename T>
class A {
public:
A(int i) : i(i) {}
explicit operator int() const {
return i;
}
private:
int i;
};
现在,我希望能够在A a(2); int i = a;
(应该是一个类)的方法中编写类似T
的东西。
我的第一个想法是利用友人声明并声明转换运算符的私有重载。但是,不允许仅基于explicit
进行重载。因此,我尝试使用const
代替它,并且有效:
template<typename T>
class A {
public:
A(int i) : i(i) {}
explicit operator int() { // Public non-const
return i;
}
private:
int i;
operator int() const { // Private const
return i;
}
friend T;
};
...直到没有。这仅在使用非常量A
时才有效,尽管我不打算使用const A
,但我仍然希望它在所有情况下都能正常工作。请注意,如果公共重载为const
,而私人重载则不是,则只能使用const A
s。
Here is a demo显示在什么情况下它起作用或不起作用。
我曾经考虑过使用volatile
(demo),虽然它做得更好,但仍然会导致相同的问题:它仅在使用非易失性A
时才有效
有更好的方法吗?更笼统地说,有没有办法解决第一句话中的问题?