在我的代码中,我有包含依赖于一些模板参数的 lambda 表达式的函数模板。最近我遇到了链接器错误,可能是由于我的 g++ 编译器的更新,但不幸的是,我并不确切知道。
我将举一个小例子来说明这个问题。因为这是一个链接器问题,我们必须创建几个文件来演示它。我们有common.hpp
,它包含一个通用模板函数,两个模块a.cpp
/a.hpp
和b.cpp
/b.hpp
使用该函数和一个main.cpp
包含该main
函数的模块。
// common.hpp
#include <algorithm>
template <class Iterator, typename Iterator::value_type x>
void
my_transform(Iterator begin, Iterator end)
{
std::transform(begin, end, begin,
[] (typename Iterator::value_type y) { return x+y; });
}
文件a.cpp
:
// a.cpp
#include "common.hpp"
#include "a.hpp"
void a(std::vector<int>& vec)
{
my_transform<std::vector<int>::iterator, 5>(vec.begin(), vec.end());
}
文件a.hpp
#include <vector>
void a(std::vector<int>& vec);
文件b.cpp
:
// b.cpp
#include "common.hpp"
#include "b.hpp"
void b(std::vector<int>& vec)
{
my_transform<std::vector<int>::iterator, 5>(vec.begin(), vec.end());
}
文件b.hpp
#include <vector>
void b(std::vector<int>& vec);
文件main.cpp
int main() { return 0; }
如果我编译和链接使用
g++-4.7 -std=c++11 -c a.cpp
g++-4.7 -std=c++11 -c b.cpp
g++-4.7 -std=c++11 -c main.cpp
g++ a.o b.o main.o
我收到一个multiple-definition
错误:
b.cpp:(.text+0x30): multiple definition of `void my_transform<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, 17>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >)::{lambda(int)#1}::operator int (*)(int)() const'
a.o:a.cpp:(.text+0x30): first defined here
基本上它说 lambda 表达式已经在 a.xml 中定义。好的。如果我将模板参数b
从 5 更改为 7,一切正常。
问题:
- 这是我应该期待的还是它的错误
g++
?我很确定我使用早期版本的 debian 包编译了这段代码g++-4.7
。 - 除了不使用 lambda 之外,还有其他解决方法吗?我认为,如果生成的符号是静态的,则不会有任何问题。更新:解决方法:制作 my_transform
static
或inline
.
这个问题不是很重要。“不要在这里使用 lambdas”方法没有问题,但我很好奇。:)