c++ - 有人可以向我解释模板解析顺序规则吗?

标签 c++ templates metaprogramming boost-mpl

好的,这里是完整的伪代码。

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

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

更新

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

谢谢大家

最佳答案

这是模板实例化工作原理的简化版本(我将完成 Boost documentation for fold )。

假设你是一个 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(这就是折叠 vector 所做的),因此它创建了一个基于 long 的新类型,其中包含所有 T填写:

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

这种类型被编译,因为它已被使用。 C++ 模板的基本规则是:当你在编译期间使用它时,它会被实例化,这意味着它会被编译。您无需在运行时执行任何特殊操作。

关于c++ - 有人可以向我解释模板解析顺序规则吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5849415/

相关文章:

functional-programming - 具有运行时访问 AST 的编程语言/平台

macros - 使用 Lisp 宏创建类似的函数

c++ - 如果模板中存在,如何获取成员函数指针

c++ - 抽象类的大小是多少?为什么我们不能创建抽象类的对象?

c++ - Microsoft Visual C++ 连接到 Unix 环境

c++ - 如何从模板函数返回模板类?

c++ - 为什么 std::string 关系运算符比较结果对于模板和函数是不同的?

c++ - 遍历 C++ 17 中的映射键

c++ - 是否可以使用 std::nothrow 参数进行放置新操作?

c++ - 类型删除和访问器