当前位置: 首页 > 知识库问答 >
问题:

C:模板专用化导致调试/发布时产生不同的结果

边明煦
2023-03-14

在下面的代码中,我创建了一个Builder模板,并提供了一个不返回任何内容的默认实现。然后我使用int专门化模板,以返回一个值37。

当我使用 -O0 编译时,代码打印 37,这是预期的结果。但是当我使用 -O3 编译时,代码打印 0。

平台是Ubuntu 20.04,GCC 9.3.0

有人能帮我理解一下这种行为吗?

建筑商. h

class Builder {
        public:
                template<typename C>
                static C build() {
                        return 0;
                }
};

builder.cc

#include "builder.h"

template<>
int Builder::build<int>() {
        return 37;
}

main.cc

#include "builder.h"
#include <iostream>

int main() {
        std::cout << Builder::build<int>() << '\n';
}

制作文件

CXX_FLAG = -O0 -g
all:
        g++ $(CXX_FLAG) builder.cc -c -o builder.o
        g++ $(CXX_FLAG) main.cc builder.o -o main
clean:
        rm *.o
        rm main

共有1个答案

闻人修平
2023-03-14

您应该为<code>构建添加正向声明

template<>
int Builder::build<int>();

否则,在编译main.cc时,编译器只能看到泛型模板,并且允许内联泛型build()函数的实例。如果您添加前置声明,编译器知道您在其他地方提供了专门化,并且不会内联它。

使用 -O3,编译器尝试内联,使用 -O0 它不会内联任何内容,因此不同。

您的代码实际上违反了“一个定义规则”:它将为Builder::build创建两个定义

 类似资料:
  • 首先,我有一个类的头文件,一个没有定义的专业化声明(来自互联网的代码示例) $ 猫 foo.h 然后有2个模板专业化的实现文件 最后我得到了一个主文件 如果我在没有优化的情况下编译并运行它,它会给出: g foo_ int。cpp foo_ float。cpp main.cpp 如果我添加优化,那么结果是不同的: $ g foo _ int . CPP foo _ float . CPP main

  • 我有一个模板函数doSomething(T),它接受任何类型的参数…类型基类除外。 所以我把doSomething模板专门用于类型Base的参数,所以它做了一些不同的事情。 然而,当我将派生类传递给doSomething时,它会打印“所有类型!”,而我希望它打印“Base!”,因为派生类本质上也是一个基类。 如果我有: 然后doSomething(d)也会打印“所有类型!”而不是“base!”,因

  • 问题: 使用继承,可以执行以下操作: ...调用foo::go()将打印“this foo Living at ” 不过,使用模板: 所有这些都与您在子类无法访问父类提供的原始版本的情况下使用虚拟方法重写时遇到的问题如出一辙。

  • 还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案

  • 问题内容: 这是我的代码: 它运作良好。但是当我尝试添加这个 我遇到编译器错误:«int MyClass :: DoSomething()»的«>»令牌模板标识«DoSomething <0>»之前的无效显式专门化与任何模板声明都不匹配 我使用g ++ 4.6.1应该怎么做? 问题答案: 不幸的是,如果不对外部模板进行特殊化处理,就不能对作为类模板成员的模板进行特殊处理: C ++ 11 14.7