C++:强制完成模板编译 (MSVC/G++)

发布于 2024-12-13 04:27:34 字数 819 浏览 3 评论 0原文

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

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

Hello and good day to you.

Following code fragment compiles on cl.exe (15.00.30729.01) and 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;
}

Also, on cl.exe you can even get away with something like this:

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

Now, this obviously happens because compiler does not create contents for methods of a template class until somebody calls them. However, this may pose problems when you're designing large template class (because you're very likely to forget to add test call to new method somewhere).

The question:
Is there a compiler switch for g++ or cl.exe that would force compiler to process entire template (so this code fragment will trigger compilation error)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

氛圍 2024-12-20 04:27:34

如果您想使用多种类型测试模板,则可以触发类型的手动实例化,如下所示:

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

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

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

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

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

If you want to test the template with a couple of types, you can trigger manual instantiations of the types, as in:

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

Explicit instantiations of class templates automatically trigger the instantiation of all members, which seems to be what you want.

The actual problem is that the language is designed to explicitly allow the behavior that you want to avoid. When a class template is implicitly instantiated, the compiler will instantiate only those methods that are used. The main use case of the feature is that some methods might impose stricter requirements on the instantiating type than others, if all methods were instantiated always then the class template could only be used with those types that fulfill the stricter requirements.

By allowing the compiler to only instantiate those methods that are used, the class template can be used with types that don't meet all of the requirements of all of the methods, as long as they meet the requirements of the methods that are actually used.

A common example is operator[] in std::map<> that requires the value_type to be default-constructible (operator[] will create a new object default initialized if the key is not present in the container and return a reference to it). The behavior in the language allows you to use std::map on types that are not default-constructible as long as you don't use operator[] (or any other member function that imposes that requirement).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文