gpt4 book ai didi

c++ - 模板特化导致 Windows 上的 MinGW 链接错误,而不是 Linux 上的 GCC

转载 作者:可可西里 更新时间:2023-11-01 09:25:05 24 4
gpt4 key购买 nike

以下build设置在使用 GCC (4.6.3) 的 Linux 上运行良好,但不适用于使用 GCC (4.7.2) 的 MinGW。


$ cat Makefile 
all:
g++ -c foo.cpp
g++ -c bar.cpp
g++ bar.o foo.o -o bar

$ cat foo.h 
#ifndef FOO_H
#define FOO_H

#include <iostream>

template <typename T>
void foo(T x) {
std::cout << "Hello World!" << std::endl;
}
#endif

$ cat foo.cpp
#include "foo.h"
template <>
void foo(int x) {
std::cout << "Hello Int!" << std::endl;
}

$ cat bar.cpp 
#include "foo.h"

int main() {
foo <int> (1);
}

在 Linux 上,我们有:

$ make
g++ -c foo.cpp
g++ -c bar.cpp
g++ bar.o foo.o -o bar

$ ./bar
Hello Int!

这是我所期望的。在 Windows 上,我们有

$ make
g++ -c foo.cpp
g++ -c bar.cpp
g++ bar.o foo.o -o bar
foo.o:foo.cpp:(.text+0x0): multiple definition of `void foo<int>(int)'
bar.o:bar.cpp:(.text$_Z3fooIiEvT_[__Z3fooIiEvT_]+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
make: *** [all] Error 1

我怀疑这与弱符号有关。意思是,在 Linux 上我们在 foo.o 中有它

00000000 T _Z3fooIiEvT_

在 bar.o 中

00000000 W _Z3fooIiEvT_

而在 Windows 上我们在 foo.o 中有它

00000000 T __Z3fooIiEvT_

在 bar.o 中

00000000 T __Z3fooIiEvT_

因此,没有可以覆盖的弱符号。

解决此问题的最佳方法是什么?在实际情况下,我有一个带有许多模板定义的 header foo.h。其中一些,我专门研究并将这些定义放在 foo.cpp 中,稍后将其编译成一个库。然后,我将标题和库提供给用户。如果可能的话,我总是想使用 foo 库中的特化。如果特化不存在,我想使用 foo header 中的模板定义。

编辑

foo.h 的以下修改似乎解决了这个问题

$ cat foo.h 
#ifndef FOO_H
#define FOO_H

#include <iostream>

template <typename T>
void foo(T x) {
std::cout << "Hello World!" << std::endl;
}
template <>
void foo(int x);
#endif

基本上,foo 的 int 版本的原型(prototype)需要在标题中。这与 BoBTFish 的注释一致,即标准要求“首次使用前应声明特化”。无论如何,这是设置专业库的最佳方式吗?

最佳答案

不知道编译器的复杂性,但无论如何你都违反了标准:

14.7.3 Explicit specialization:

6 If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.

所以你的程序格式错误。

关于c++ - 模板特化导致 Windows 上的 MinGW 链接错误,而不是 Linux 上的 GCC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17720424/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com