我正在尝试构建一个带有转换保护措施的指针类来监控指针转换。具体来说,我希望它在断言内部执行dynamic_cast,并确保结果不是nullptr。不幸的是,如果指针没有指向类类型,它会给出一个编译时错误,指示不能使用dynamic_cast。
接下来我尝试了:
assert( (std::is_same<T,T2>() || dynamic_cast<T*>(in_ptr)) );
......但这种方法仍然无效,因为短路只发生在运行时;发生了同样的错误。
我的下一个想法是构建一个专门的convert_ok
结构,如果两个指针都相同,则operator()返回true,否则返回dynamic_cast的bool结果。
我认为这种方法可行,但我觉得我必须遗漏标准库中的内容。 std::is_convertable
接近,但是当从基类移动到派生类时,它只能在运行时知道转换是否合法...因此是动态转换。
为什么:因为我知道人们会问,我已经建立了一个Ptr模板,当设置NDEBUG时,该模板会缩减为常规指针,但如果发生内存问题,则会引用计数和跳闸断言(引用计数变为0)没有删除,删除后访问指针,多次删除指针等等。)它比智能指针更适合我,因为它在调试模式下执行更多簿记,而在设置NDEBUG时具有接近零的开销。它已经帮助我清理了一些棘手的指针玩杂耍,我现在正致力于扩展其功能。
答案 0 :(得分:1)
将11 #if GOOGLE_PROTOBUF_VERSION < 3002000
与测试结合使用,以确定
12 #error This file was generated by a newer version of protoc which is
13 #error incompatible with your Protocol Buffer headers. Please update
14 #error your headers.
15 #endif
16 #if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
17 #error This file was generated by an older version of protoc which is
18 #error incompatible with your Protocol Buffer headers. Please
19 #error regenerate this file with a newer version of protoc.
20 #endifstd::enable_if
是否适合SFINAE正确的断言。这样可以避免在dynamic_cast
出错时使用dynamic_cast
,例如:
A
投射到类类型B
,其中B
不是A
的可访问基础。我正在使用this boilerplate来实施测试。
template <typename T, typename U>
using dynamic_cast_r = decltype(dynamic_cast<U*>(static_cast<T*>(nullptr)));
template <typename T, typename U>
using can_dynamic_cast = can_apply<dynamic_cast_r, T, U>;
template <typename T>
class foo
{
public:
foo(T *p) : p(p) { }
public:
template <typename U>
typename std::enable_if<can_dynamic_cast<T, U>::value, bool>::type convert_ok()
{
return dynamic_cast<U*>(p) != nullptr;
}
template <typename U>
typename std::enable_if<!can_dynamic_cast<T, U>::value, bool>::type convert_ok()
{
return std::is_same<T, U>::value;
}
private:
T *p;
};