强制完成模板编译(MSVC/ g++)

C++: force complete template compilation (MSVC/G++)

本文关键字:MSVC g++ 编译      更新时间:2023-10-16

你好,祝你一天好。

以下代码片段在cl.exe(15.00.30729.01)和mingw-g++(4.4.0)上编译:

template<typename T> class Test{
public:
    T t;
    void error(){
        int doesNotExist = 6;
        return doesNotExist;//<---- void function returning result
    }
};
int main(int argc, char** argv){
    Test<int> test;
    return 0;
}

同样,在cl.exe上,你甚至可以这样做:

template<typename T> class Test{
public:
    T t;
    void error(){
        doesNotExist = 6;//<---- undeclared variable
        return doesNotExist;//<---- void function returning result
    }
};

现在,这显然发生了,因为编译器不会为模板类的方法创建内容,直到有人调用它们。然而,当您设计大型模板类时,这可能会带来问题(因为您很可能忘记在某处添加对新方法的测试调用)。

:
g++或cl.exe的编译器开关是否会强制编译器处理整个模板(因此此代码片段将触发编译错误)?

如果您想用几个类型测试模板,您可以触发这些类型的手动实例化,如下所示:

// at namespace level
template class Test<int>;

类模板的显式实例化会自动触发所有成员的实例化,这似乎是您想要的。

实际的问题是该语言被设计成显式地允许您想要避免的行为。当隐式实例化类模板时,编译器将只实例化使用的方法。该特性的主要用例是某些方法可能对实例化类型施加比其他方法更严格的要求,如果所有方法都被实例化总是,那么类模板只能与满足更严格要求的类型一起使用。

通过允许编译器只实例化那些被使用的方法,类模板可以用于不满足所有方法的所有要求的类型,只要它们满足实际使用的方法的要求。

一个常见的例子是std::map<>中的operator[],它要求value_type默认可构造的 (operator[]将创建一个新的对象默认初始化,如果键不存在于容器中,并返回对它的引用)。该语言的行为允许您在非默认可构造的类型上使用std::map,只要您不使用operator[](或任何其他强加该要求的成员函数)。