c++ - 这个模板函数是如何工作的?它检查运行时是否可以进行类型转换,而不使用强制转换
问题描述
/// Segédsablon típuskonverzió futás közbeni ellenőrzésere
///That translates into: Helper-template to test type conversion during runtime
template <typename F, typename T>
struct _Is_Types {
template<typename D> static char (&f(D))[1];
template<typename D> static char (&f(...))[2];
static bool const convertable = sizeof(f<T>(F())) == 1;
};
这是一个代码片段,用于测试您是否可以将 F 转换为 T(或者我告诉我),但我真的不明白。请帮我
#编辑1:
所以我必须扩展一个骨架代码,其中一个测试(使用 gtest_lite)看起来像这样:
TEST(Elkeszult0, sanity_check) {
if (_Has_String<UString>::member == false)
FAIL() << "No inheritance" << endl;
if (_Is_Types<UString, String>::convertable == false)
FAIL() << "UString can't be converted to String!" << endl;
if (_Is_Types<String, UString>::convertable == false)
FAIL() << "String can't be converted to UString!" << endl;
} ENDM
#编辑2
class String
{
public:
};
class UString : public String
{
public:
};
template <typename F, typename T>
struct _Is_Types {
template<typename D> static char (&f(D))[1];
template<typename D> static char (&f(...))[2];
static bool const convertable = sizeof(f<T>(F())) == 1;
};
/* First instantiated from: insights.cpp:10 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
struct _Is_Types<String, UString>
{
template<typename D>
static char (&f(D))[1];
template<typename D>
static char (&f(, ...))[2];
#ifdef INSIGHTS_USE_TEMPLATE
template<>
static char (&f<UString>(, ...))[2];
#endif
static const bool convertable = sizeof(f<UString>(String())) == 1;
};
#endif
int main()
{
_Is_Types<String, UString>::convertable;
return 0;
}
这并没有真正帮助我理解它。那么D型爆炸成什么?它甚至可以做什么,放在函数定义之前?什么是“f”?
解决方案
检查实际上是在编译时完成的。
让我们分析一下每一行的作用。
template<typename D> static char (&f(D))[1];
这一行声明f
了一个函数,它接受一个类型的参数D
并返回一个对 a 的引用char[1]
。
template<typename D> static char (&f(...))[2];
此行作为一个函数重载f
,该函数接受任何参数并返回对 a 的引用char[2]
。
static bool const convertable = sizeof(f<T>(F())) == 1;
最后,评估可兑换性。f<T>(F())
尝试f<T>
使用类型参数调用F
。如果F
可转换为T
,则选择第一个重载,返回类型为char(&)[1]
。否则,选择另一个重载,返回类型为char(&)[2]
. 使用sizeof
运算符,我们确定选择了哪个重载,现在我们知道是否F
可以转换为T
.
请注意,这仅在F
默认可构造时才有效。
推荐阅读
- c# - c# 只返回一个对象请求的属性
- node.js - Postgres 使用 TypeOrm 级联删除:表“table1”上的更新或删除违反了表“table2”上的外键约束
- netty - MessageListener 停止监听 HornetQ 队列
- javascript - 向 Javascript 对象添加属性
- c++ - 如何使用 std::unique 删除向量中的唯一字符(C++)
- javascript - 在鼠标光标悬停时播放选定的视频/光标关闭时暂停
- oracle - 循环遍历数组以获取 where 条件 pl/sql
- php - 在codeigniter中上传图片Rest api
- android - 在特定设备上使用 Let's Encrypt 的 ERR_SSL_PROTOCOL_ERROR
- java - 无法使用 Groovy/Grails Tool Suite 在 grails 项目中打开文件