温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c++ - Why do compiler options impact selection of template implementation?
c++ g++ templates

c++ - 为什么编译器选项会影响模板实现的选择?

发布于 2020-03-27 10:34:50

根据我是使用-O3编译还是未经优化而编译,编译器不会选择相同的function-template-instanciation。使用gcc(Debian 8.3.0-6)8.3.0。

由于疏忽,我在函数模板声明中有一个默认实现:

#pragma once

#include <iostream>

template <int>
void func() { std::cerr << "default impl\n"; } // normally no impl here

及其专业:

#include "func.h"

template <>
void func<1>()
{
    std::cerr << "special 1\n";
}

template <>
void func<2>()
{
    std::cerr << "special 2\n";
}

和主要功能。

#include "func.h"

int main(void)
{
    func<1>();
    func<2>();

    return 0;
}

编译并运行可以g++ -Wall func.cpp main.cpp -o main && ./main得到:

special 1
special 2

使用优化可以g++ -O3 -Wall func.cpp main.cpp -o main && ./main得出:

default impl
default impl

这是预期的吗?代码是否触发了我不知道的意外行为?

感谢@NathanOliver提出了Wandbox的评论进行优化或不进行优化都会显示不同的输出。

查看更多

查看更多

提问者
Patrick B.
被浏览
208
StoryTeller - Unslander Monica 2019-07-03 21:46

您的代码格式错误,无需诊断。因此,不同优化级别的不同行为是可能的。

[temp.expl.spec]

6如果一个模板,一个成员模板或一个类模板的成员被明确地专门化,则应在首次使用该专门化之前声明该专门化,这将在每个使用该翻译的翻译单元中引起隐式实例化发生 无需诊断。如果程序没有为显式专门化提供定义,并且以某种方式使用专门化会导致隐式实例化,或者该成员是虚拟成员函数,则该程序格式错误,无需诊断。对于已声明但未定义的显式专门化,永远不会生成隐式实例化。

功能模板专用于一个TU,但是另一个没有可用的专用声明。积极的优化器很可能会选择隐式实例化(可在线使用),而不是在其他地方找到您创建的实例化实例。解决方案是声明标头中存在您的专业化知识。