使方法明确,除了朋友 类
Make method explicit except for friend classes
我正在尝试创建一个默认情况下显式的转换运算符,除了一些指定的 classes。
更准确地说,我有一个相对简单的 class 模板,其实例应该可以转换为其他类型(为简单起见,int
在整个问题中)。但是,我希望这种转换默认是显式的,但仍然允许它对另一个 class 是隐式的,即作为模板参数传递的 class。没有这最后一部分,这就是它的样子:
template<typename T>
class A {
public:
A(int i) : i(i) {}
explicit operator int() const {
return i;
}
private:
int i;
};
现在,我希望能够在 T
(应该是 class)的方法中编写类似 A a(2); int i = a;
的内容。
我的第一个想法是利用友元声明并声明转换运算符的私有重载。但是,不允许仅基于 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
s 时有效,虽然我不打算使用 const A
s,但我仍然希望它在所有情况下都能正常工作。请注意,如果 public 重载是 const
而私有重载不是,则这仅适用于 const A
s.
Here is a demo 显示它在哪些情况下有效或无效。
我想过使用volatile
(demo),虽然它使它变得更好,但仍然导致同样的问题:它仅在使用非易失性时有效A
s.
有更好的方法吗?更笼统地说,有没有办法解决第一句话中的问题?
显然没有令人满意的解决方案。 volatile
选项似乎是最实用的,虽然它不太适用于 volatile A
s,但额外的 const_cast
解决了这个问题。
template<typename T>
class A {
public:
A(int i) : i(i) {}
explicit operator int() const {
return i;
}
private:
int i;
operator int() const volatile {
return static_cast<int>(const_cast<A const&>(*this));
// or just
// return i;
}
friend T;
};
正如 Sneftel 在评论中所述,访问权限往往是在拉动的基础上 (using
) 而不是推送的基础上授予的。这可能就是为什么该语言没有提供一种方法来根据 class 或块执行转换来更改转换语义。
我正在尝试创建一个默认情况下显式的转换运算符,除了一些指定的 classes。
更准确地说,我有一个相对简单的 class 模板,其实例应该可以转换为其他类型(为简单起见,int
在整个问题中)。但是,我希望这种转换默认是显式的,但仍然允许它对另一个 class 是隐式的,即作为模板参数传递的 class。没有这最后一部分,这就是它的样子:
template<typename T>
class A {
public:
A(int i) : i(i) {}
explicit operator int() const {
return i;
}
private:
int i;
};
现在,我希望能够在 T
(应该是 class)的方法中编写类似 A a(2); int i = a;
的内容。
我的第一个想法是利用友元声明并声明转换运算符的私有重载。但是,不允许仅基于 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
s 时有效,虽然我不打算使用 const A
s,但我仍然希望它在所有情况下都能正常工作。请注意,如果 public 重载是 const
而私有重载不是,则这仅适用于 const A
s.
Here is a demo 显示它在哪些情况下有效或无效。
我想过使用volatile
(demo),虽然它使它变得更好,但仍然导致同样的问题:它仅在使用非易失性时有效A
s.
有更好的方法吗?更笼统地说,有没有办法解决第一句话中的问题?
显然没有令人满意的解决方案。 volatile
选项似乎是最实用的,虽然它不太适用于 volatile A
s,但额外的 const_cast
解决了这个问题。
template<typename T>
class A {
public:
A(int i) : i(i) {}
explicit operator int() const {
return i;
}
private:
int i;
operator int() const volatile {
return static_cast<int>(const_cast<A const&>(*this));
// or just
// return i;
}
friend T;
};
正如 Sneftel 在评论中所述,访问权限往往是在拉动的基础上 (using
) 而不是推送的基础上授予的。这可能就是为什么该语言没有提供一种方法来根据 class 或块执行转换来更改转换语义。