为什么这些条件不适用于模板类型?
why shouldn't these conditions work for template types?
作为我的 ,我正在尝试建立一个条件来检查两种类型,检查我是否应该 dynamic_cast
。
我有以下条件:
#define can_dynamic_cast(FROM, TO) \
can_cast(FROM, TO) && \
!std::is_same<FROM, TO>::value && \
std::is_class<TO>::value && \
!std::is_const<FROM>::value && \
std::is_base_of<TO, FROM>::value
它不适用于以下基本检查,can_dynamic_cast
将 return 为真!!!
static_assert(!can_dynamic_cast(int, int), "didn't expecting dynamic cast, but could!")
出于绝望,我降到了以下条件,但仍然没有希望!
#define can_dynamic_cast(FROM, TO) \
std::is_convertible<FROM, TO>::value && \
std::is_class<TO>::value && \
std::is_class<FROM>::value
以上条件是最基本的条件,can_dynamic_cast
会returntrue
再(int, int)
,这是不应该的!!!
问题
1) 我没看错什么?
总结一下评论中给出的解决方案和答案:(感谢T.C.和AntonSavin)
你的宏不是完全错误,但它是一个宏。预处理器简单地用宏的内容替换宏调用:
static_assert(!can_dynamic_cast(int, int), "...");
// =>
static_assert(!std::is_convertible<int, int>::value &&
std::is_class<int>::value &&
std::is_class<int>::value , "...");
因此,只有第一个值被取反,这会产生意外行为。
要解决这个问题,您必须在宏定义或宏调用中添加方括号:
#define can_dynamic_cast(FROM, TO) \
( std::is_convertible<FROM, TO>::value && \
std::is_class<TO>::value && \
std::is_class<FROM>::value )
// or
static_assert(!(can_dynamic_cast(int, int)), "...");
更好的解决方案而不是更长的解决方案是创建自己的类型特征 class:
template <class FROM, class TO>
struct can_dynamic_cast : std::integral_constant< bool,
std::is_convertible<FROM, TO>::value &&
std::is_class<TO>::value &&
std::is_class<FROM>::value > {};
static_assert(!can_dynamic_cast<int, int>::value, "...");
它不太容易出错,因为它在元函数调用中遵循 c++ 语法并且不需要额外的括号。
作为我的 dynamic_cast
。
我有以下条件:
#define can_dynamic_cast(FROM, TO) \
can_cast(FROM, TO) && \
!std::is_same<FROM, TO>::value && \
std::is_class<TO>::value && \
!std::is_const<FROM>::value && \
std::is_base_of<TO, FROM>::value
它不适用于以下基本检查,can_dynamic_cast
将 return 为真!!!
static_assert(!can_dynamic_cast(int, int), "didn't expecting dynamic cast, but could!")
出于绝望,我降到了以下条件,但仍然没有希望!
#define can_dynamic_cast(FROM, TO) \
std::is_convertible<FROM, TO>::value && \
std::is_class<TO>::value && \
std::is_class<FROM>::value
以上条件是最基本的条件,can_dynamic_cast
会returntrue
再(int, int)
,这是不应该的!!!
问题
1) 我没看错什么?
总结一下评论中给出的解决方案和答案:(感谢T.C.和AntonSavin)
你的宏不是完全错误,但它是一个宏。预处理器简单地用宏的内容替换宏调用:
static_assert(!can_dynamic_cast(int, int), "...");
// =>
static_assert(!std::is_convertible<int, int>::value &&
std::is_class<int>::value &&
std::is_class<int>::value , "...");
因此,只有第一个值被取反,这会产生意外行为。
要解决这个问题,您必须在宏定义或宏调用中添加方括号:
#define can_dynamic_cast(FROM, TO) \
( std::is_convertible<FROM, TO>::value && \
std::is_class<TO>::value && \
std::is_class<FROM>::value )
// or
static_assert(!(can_dynamic_cast(int, int)), "...");
更好的解决方案而不是更长的解决方案是创建自己的类型特征 class:
template <class FROM, class TO>
struct can_dynamic_cast : std::integral_constant< bool,
std::is_convertible<FROM, TO>::value &&
std::is_class<TO>::value &&
std::is_class<FROM>::value > {};
static_assert(!can_dynamic_cast<int, int>::value, "...");
它不太容易出错,因为它在元函数调用中遵循 c++ 语法并且不需要额外的括号。