joa*_*dre 0 c++ casting static-cast
考虑在类模板func中声明以下函数模板:MyClass
template < T >
class MyClass {
public:
MyClass() = default;
// ...
template < typename oT >
oT func() {
return static_cast< oT >(_m); // alternative, return oT(_m);
}
// ...
protected:
T _m;
};
Run Code Online (Sandbox Code Playgroud)
static_cast< oT >(_m)调用显式实例化有什么优势吗oT(_m)?
oT(_m)将允许比预期更多的转换。如果static_cast<oT>(_m)不可能,那么oT(_m)也会尝试 a const_cast,static_cast然后是const_cast,reinterpret_cast然后reinterpret_cast是const_cast。
例如,如果Tisconst int*和oTis double*,则 thenoT(_m)将成功,而 whilestatic_cast<oT>(_m)将失败。但是将 from 的结果oT(_m)当作指向 a 的指针使用double会导致未定义的行为。
如果T和oT是指向类的指针,则可能更危险,因为oT(_m)无论两个类之间是否存在继承关系,都将始终编译。
甚至static_cast允许一些可能不是预期的转换。例如,它可以向下转换指向类的指针。
另一种选择很简单return _m;。这比上面的两个变体都要弱。它只允许复制初始化。然而,根据您的用例,这可能太弱了。例如,它不会使用显式构造函数和转换函数。另一方面,在 C++17 之前,它不需要oT可移动构造,而前两个变体在 C++17 之前确实需要移动构造。
因此,您需要决定哪些强制转换应该被允许,哪些强制转换应该失败。
然而,无论如何,没有什么可以阻止用户调用func<T>()来获取原始类型,然后用户可以根据自己的喜好简单地转换它,所以我不确定通过简单的 getter 在这里可以获得什么。
更重要的是,在任何一种情况下,用户都可以调用func<T&>()并获得对该成员的引用,从而使这变得protected毫无意义。也许允许的类型T需要通过 SFINAE/requires-clause 进行约束。
| 归档时间: |
|
| 查看次数: |
227 次 |
| 最近记录: |