【问题标题】:C++: force complete template compilation (MSVC/G++)C++:强制完成模板编译(MSVC/G++)
【发布时间】:2011-12-20 05:16:51
【问题描述】:

你好,祝你有美好的一天。

以下代码片段在 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 的编译器开关会强制编译器处理整个模板(因此此代码片段会触发编译错误)?

【问题讨论】:

    标签: c++ visual-studio-2008 templates visual-c++ g++


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 是的,显式模板实例化就是您想要的。另见:msdn.microsoft.com/en-us/library/by56e477%28VS.80%29.aspx
    • 很好地解释了没有编译器错误的实际目的。
    • 好的,它有效。我接受你的回答,但没有必要解释为什么它会这样工作(我已经知道了)。感谢您的回复。
    猜你喜欢
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 2015-07-27
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多