【发布时间】:2020-05-30 21:32:44
【问题描述】:
我有这个最小的工作示例(我故意在这里使用cstdio 以保持nm 输出可读):
// main.cpp
#include "cstdio"
#include "foo.hpp"
int main() {
Foo<int> foo{42};
Foo<int> bar{42};
bool b = foo == bar;
printf("%d\n", b);
return 0;
}
// foo.hpp
#pragma once
template<typename T>
struct Foo {
Foo(T foo_) : foo{foo_} {}
T foo;
friend bool operator==(const Foo<T> &lhs, const Foo<T> &rhs);
};
// foo.cpp
#include "foo.hpp"
template<typename T>
bool operator==(const Foo<T> &lhs, const Foo<T> &rhs) {
return false;
}
template struct Foo<int>;
template bool operator==(const Foo<int> &lhs, const Foo<int> &rhs);
我是这样构建的:
clang --std=c++2a -lstdc++ main.cpp foo.cpp
失败了
Undefined symbols for architecture x86_64:
"operator==(Foo<int> const&, Foo<int> const&)", referenced from:
_main in main-3d7fff.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
尽管我明确实例化了operator== 模板。
我已经分别重建了每个文件:
clang --std=c++2a -c main.cpp
clang --std=c++2a -c foo.cpp
并通过nm 进行了探索:
main.o: 0000000000000060 T Foo<int>::Foo(int)
main.o: 0000000000000090 T Foo<int>::Foo(int)
main.o: U operator==(Foo<int> const&, Foo<int> const&)
main.o: 0000000000000000 T _main
main.o: U _printf
foo.o: 0000000000000020 T Foo<int>::Foo(int)
foo.o: 0000000000000000 T Foo<int>::Foo(int)
foo.o: 0000000000000050 T bool operator==<int>(Foo<int> const&, Foo<int> const&)
尽管这两个签名对我来说看起来兼容,但当我尝试链接它时,它失败了:
$ ld -lc foo.o main.o 2>&1 | c++filt
Undefined symbols for architecture x86_64:
"operator==(Foo<int> const&, Foo<int> const&)", referenced from:
_main in main.o
ld: symbol(short) not found for architecture x86_64
为什么?我该如何解决这个问题?
【问题讨论】: