g++ -fopenmp main.cpp
提示未定义对 std::vector
的引用。如何解决这个问题?
我已经在 Ubuntu 上安装了 libomp-dev
包。
主要.cpp
#include<vector>
#include<iostream>
template<typename T, typename A>
T recursiveSumBody(std::vector<T, A> &vec) {
T sum = 0;
#pragma omp task shared(sum)
{
sum = recursiveSumBody(vec);
}
return vec[0];
}
int main() {
std::vector<int> a;
recursiveSumBody(a);
return 0;
}
undefined reference
/tmp/ccTDECNm.o: In function `int recursiveSumBody<int, std::allocator<int> >(std::vector<int, std::allocator<int> >&) [clone ._omp_cpyfn.1]':
main.cpp:(.text+0x148): undefined reference to `std::vector<int, std::allocator<int> >::vector(std::vector<int, std::allocator<int> > const&)'
collect2: error: ld returned 1 exit status
最佳答案
要解决此问题,您可以手动指定 shared(sum, vec)
(强烈假设您希望共享它)。
有趣的是,较旧的 gcc 版本(例如 5.4.0)提供了更有用的错误消息:
error: 'vec' implicitly determined as 'firstprivate' has reference type
而英特尔编译器 icpc 17.0.1
给出一个“internal error : 0_1855
”。
手动指定 firstprivate
或 private
- 这对您来说毫无意义 - 会导致其他更具描述性的错误。请注意,正如 Hristo Iliev 在其他评论中解释的那样,firstprivate
将意味着为每个线程创建 vector 的拷贝。
根据当前 (4.5) 标准:
In an orphaned task generating construct, if no default clause is present, formal arguments passed by reference are
firstprivate
.
我想这适用于此。进一步,
A variable that appears in a
firstprivate
clause must not have an incomplete C/C++ type or be a reference to an incomplete type. If a list item in afirstprivate
clause on a worksharing construct has a reference type then it must bind to the same object for all threads of the team.
它没有出现在条款中,但我认为这仍然是标准的意思。
现在我不认为std::vector<T, A>
是模板中的不完整类型,除非我遗漏了有关模板如何实例化的信息。所以我确实认为您的代码应该是有效的,并且考虑到每个线程只绑定(bind)到同一个对象,它实际上是有意义的。
所以我确实认为这是最近 gcc
中的一个错误版本以及英特尔编译器。看起来编译器无法为模板实例化某些东西。
进一步,添加:
if (0) std::vector<T, A> wtf = vec;
在函数的开头使代码编译并链接到gcc
.但是如果 firstprivate
手动添加,gcc 继续提示 'vec' has incomplete type
.
P.S.: 在 OpenMP 4.5 中添加了在数据共享属性子句中允许引用类型,这是旧的 gcc 给出了不同的错误。
关于c++ - OpenMp 任务 : can't pass argument by reference,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43900638/