为什么这些条件不适用于模板类型?
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
将返回true!!!
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
会再次为(int, int)
返回true
,这是不可能的!!!
问题
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)), "...");
一个更好的解决方案,而不是更长的解决方案是创建一个自己的类型特征类:
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++语法,不需要额外的括号。
相关文章:
- FLTK 2.0构建和演示,适用于VS2019的2011年左右的代码库
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 适用于 WebView2 旧版本的示例应用程序
- 在 NVIDIA GEFORCE GTX 1050 上下载适用于 Windows 10 的 openCL 1.2
- __attribute__(优化(0))) 是否适用于"recursively"?
- 为什么 std::erase(std::erase_if) 不是适用于<algorithm>任何容器的模板?
- 使用一个参数的模板函数时出错(适用于 2)
- 将 2D 矢量转换为 C 类型的最佳方法(适用于 SGX 飞地)
- OpenCL 的 clEnqueueReadBufferRect 适用于 int 但不适用于 double 数据类型
- 声明适用于 auto,但不能显式声明类型?
- 无法获得 boost::spirit parser&lexer 适用于 std::string 或 int 或 double 以外的令牌类型
- 为什么模板函数只基于返回类型适用于C++
- CRC计算模板适用于除CRC8以外的所有类型
- 哪些适用于 Windows 的 C++11 编译器支持新的类型特征,如"is_nothrow_move_constructible"?
- 类模板仅适用于2种类型
- 模板的类型定义包括char[][] - 适用于VS2008,但不适用于gcc
- 适用于Microsoft Visual C++2008和R2007b的Mex类型
- sizeof 如何适用于 int 类型
- 适用于 C、C++ 或 .NET 的"Sparse Map"数据类型(类似 RLE)