c++ - 在 C++ 中编译时间类型确定

标签 c++ inheritance templates types

一位同事最近向我展示了他在网上找到的一些代码。它似乎允许编译时确定一个类型是否与另一种类型具有"is"关系。我认为这非常棒,但我不得不承认我对它的实际工作原理一无所知。谁能给我解释一下?

template<typename BaseT, typename DerivedT>
inline bool isRelated(const DerivedT&)
{
    DerivedT derived();
    char test(const BaseT&); // sizeof(test()) == sizeof(char)
    char (&test(...))[2];    // sizeof(test()) == sizeof(char[2])
    struct conversion 
    { 
        enum { exists = (sizeof(test(derived())) == sizeof(char)) }; 
    };
    return conversion::exists;
} 

一旦定义了这个函数,你就可以像这样使用它:

#include <iostream>

class base {};
class derived : public base {};
class unrelated {};

int main()
{
    base b;
    derived d;
    unrelated u;

    if( isRelated<base>( b ) )
        std::cout << "b is related to base" << std::endl;

    if( isRelated<base>( d ) )
        std::cout << "d is related to base" << std::endl;

    if( !isRelated<base>( u ) )
        std::cout << "u is not related to base" << std::endl;
} 

最佳答案

它声明了两个名为 test 的重载函数,一个采用 Base,一个采用任何 (...),并返回不同的类型.

然后它使用 Derived 调用函数并检查其返回类型的大小以查看调用了哪个重载。 (实际上是用返回Derived的函数的返回值调用函数,避免占用内存)

因为 enum 是编译时常量,所有这些都是在编译时在类型系统中完成的。由于函数最终不会在运行时被调用,因此它们没有主体并不重要。

关于c++ - 在 C++ 中编译时间类型确定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2633787/

相关文章:

c++ - 模板特化 : non-inline function definition issue

C++数据结构代替数据库

c++ - 在 C++ 中通过引用传递时参数的默认值

c++ - 如何有效地使用 boost::process::async_pipe 进行写入和读取?

c++ - float128 和 double-double 运算

java - 当没有构造函数的类的默认构造函数是 'automatically' 时,为什么编译器会提示父类(super class)没有构造函数?

c++ - 在继承模板类中使用下标[]运算符

jpa - 使用 Eclipselink/JPA 更改实体类型?

ios - 在 iPad 中从基于 Window 的应用程序转换为基于 View 的应用程序

c++ - 模板中显式参数的转换