有人能给我解释一下模板解析顺序规则吗?

Could somebody explain the template resolution order rules to me?

本文关键字:顺序 规则 一下 解释      更新时间:2023-10-16

好的,在这里完成伪代码。

template <typename T>
void fun(/*...*/)
{
    some_meta_typelist pushback T;
}

所以这个想法是,在这个函数被实例化的任何时候,它都会增长some_meta_typelist对象。如果这是跨边界完成的,是否保证在类型列表在MPL::fold函数中使用之前,所有对该模板构建机制的调用都将被编译?什么时候评估这些,什么时候能确定它们已经完成?这是否应该限制在编译单元中,并且永远不要跨越.cpp的边界?是否有一个等效的调用函数与一个静态变量,以确保对象已创建之前使用?

我正在考虑这样一种想法,即调用系统的对象将构建系统需要完成其工作的类型列表。我的感觉是,类型列表将完全取决于编译顺序,因此除了单个文件CPP之外,它不是一种有效的方法。我知道MSVC按字母顺序编译,或者至少过去是这样,所以我可以将最终文件命名为ZZZZ.cpp,这里的最终文件是指需要完全构建的类型列表的文件。这不是一个安全或兼容的解决方案。是这样吗?有解决办法吗?

谢谢所有的

这是模板实例化如何工作的一个简单的,淡化的版本(我将通过Boost文档来完成折叠)。

假设你是一个c++编译器(让我们叫你clang…这是一个很酷的名字),你很高兴地阅读一个.cpp文件,以便编译它。你可以看到这些正常的函数,比如void foo(), float magic(int x, double p)int main(int argc, char** argv)。然后,你会遇到这样的东西:

template <typename T>
struct is_fun
{
    typedef some_other_type<T> something_else;
    typedef typename something_else::value value;
}

这里,clang说:酷,我知道这个名为is_fun的结构,它是一个模板,只有一个类型作为参数。此时,is_fun是一个未初始化的模板。需要注意的是,这里没有编译任何东西。当clang看到一个模板化的东西时,它检查语法(在它能够检查的范围内),然后继续。没有办法在目标代码中发出未初始化的模板——它是纯粹的c++,没有经过编译。

之后,它出现了,并且看到is_fun在这样的语句中使用:

typedef vector<long,float,short,double,float,long,long double> types;
typedef fold<
             types,
             int_<0>,
             if_< is_fun<_2>,next<_1>,_1 >
            >
        ::type number_of_fun;

现在,clang很懒,只是说"好吧,number_of_fun只是那个丑陋的东西的别名。"同样,不做任何事情。在后面的代码中,它看到如下内容:

int foo()
{
    const int fun = number_of_fun::value;
    return fun;
}

现在,它对number_of_fun模板做了一些事情。现在,将用值填充模板参数(因为使用number_of_fun::value需要它)。clang将逐步完成所有的Boost内容,并最终以模板化的is_fun结束。它需要的第一件事是long(这就是折叠向量的作用),所以它创建了一个基于long的新类型,并填充了所有的T:

struct is_fun<long>
{
    typedef some_other_type<long> something_else;
    static const int value = typename something_else::value;
}

这个类型将被编译,因为它已经被使用了。c++模板的基本规则是:当您在编译期间使用它时,它将被实例化,这意味着它将被编译。在运行时不需要做什么特别的事情。