Mar*_*ngs 7 c++ casting implicit-conversion visual-studio-2012
从我的包装器类开始,Pointer<Base>我只想返回指向const的指针:Base const *.
当转换Pointer<Base>为Derived const *我得到编译错误:
错误C2440:'static_cast':'指针'无法转换为'const Derived*'
(翻译自德语VS2012)
struct Base { };
struct Derived : public Base { };
template <typename T>
class Pointer {
public:
Pointer(T *t = nullptr) : p(t) { }
//operator T*() { return p; }
operator T const *() const { return p; }
template <typename U>
inline U staticCast() const { return static_cast<U>(d); }
private:
T *p;
};
int main(int argc, char *argv[]) {
Derived d;
Pointer<Base> p(&d);
Derived const *pd = static_cast<Derived const *>(p);
}
Run Code Online (Sandbox Code Playgroud)
如果我启用转换operator T*() { return p; }它可以工作.
为什么不static_cast使用const转换运算符?
或者更具体地说,因为
Derived const *pd = static_cast<Derived const *>(static_cast<Base const *>(p));
Run Code Online (Sandbox Code Playgroud)
作品:
为什么可以static_cast隐式地转换为Base *,但不是Base const *,即使后者对于转换目标类型是足够的?
标准说:
如果存在从表达式到new_type的隐式转换序列,或者如果从表达式直接初始化对象或类型new_type的引用的重载解析将找到至少一个可行函数,则static_cast(expression)返回初始化为的虚构变量Temp if by new_type Temp(expression);,可能涉及隐式转换,调用new_type的构造函数或调用用户定义的转换运算符.
[由我强调]
解决方法
由于这似乎是一个VisualStudio错误,我将通过模板化成员函数staticCast()(参见上面的示例代码)使用解决方法,使用如下:
Derived const *pd = p.staticCast<Derived const *>();
Run Code Online (Sandbox Code Playgroud)
要仅允许强制转换U const *,请使用SFINAE:
template <typename U>
struct is_pointer_to_const
{
static const bool value = std::is_pointer<U>::value
&& std::is_const<typename std::remove_pointer<U>::type >::value;
};
template <typename U>
inline U staticCast(typename std::enable_if<is_pointer_to_const<U>::value >::type* = 0) const
{ return static_cast<U>(d); }
template <typename U>
inline U staticCast(typename std::enable_if<!is_pointer_to_const<U>::value >::type* = 0) const
{ static_assert(false, "Type is not a pointer to const"); return U(); }
Run Code Online (Sandbox Code Playgroud)
只允许一种转换,因此您可以转换为Base,但之后无法转换为Derived。
所以你必须使用两次连续的演员。无论如何,它更安全,因为您声明您知道您正在从 a 转换Base为 a Derived。永远不应该进行从基类到派生类的隐式转换。
| 归档时间: |
|
| 查看次数: |
249 次 |
| 最近记录: |