c ++ 11 std::async 在 mingw 中不起作用

2021-12-28 00:00:00 concurrency mingw c++ c++11 stdasync

从 Herb Sutter 的演示文稿中运行此代码.这在 gcc 4.6.3 下的 linux 中工作正常.我认为mingw不支持future.h,但错误真的很难理解!

Running this code from Herb Sutter's presentation. This works fine in linux under gcc 4.6.3. I'm thinking that future.h isn't supported in mingw, but the error is really hard to understand!

#include <iostream>
#include <vector>
#include <string>
#include <future>
#include <algorithm>

using namespace std;

string flip( string s ) {
  reverse( begin(s), end(s) );
  return s;
}

int main() {
  vector<future<string>> v;

  v.push_back( async([]{ return flip(" ,olleH"); }) );
  v.push_back( async([]{ return flip(".gnaL"); }) );
  v.push_back( async([]{ return flip("
!TXEN"); }) );

  for( auto& e: v ) {
    cout << e.get();
  }
}

这里是错误:

$ x86_64-w64-mingw32-g++.exe -std=c++0x -pthread swap.cpp
swap.cpp: In function 'int main()':
swap.cpp:17:51: error: invalid use of incomplete type 'std::__async_sfinae_helper<main()::<lambda()>, main()::<lambda()> >::type {aka class std::future<std::basic_string<char> >}'
In file included from swap.cpp:4:0:
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/future:111:11: error: declaration of 'std::__async_sfinae_helper<main()::<lambda()>, main()::<lambda()> >::type {aka class std::future<std::basic_string<char> >}'
swap.cpp:18:49: error: invalid use of incomplete type 'std::__async_sfinae_helper<main()::<lambda()>, main()::<lambda()> >::type {aka class std::future<std::basic_string<char> >}'
In file included from swap.cpp:4:0:
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/future:111:11: error: declaration of 'std::__async_sfinae_helper<main()::<lambda()>, main()::<lambda()> >::type {aka class std::future<std::basic_string<char> >}'
swap.cpp:19:51: error: invalid use of incomplete type 'std::__async_sfinae_helper<main()::<lambda()>, main()::<lambda()> >::type {aka class std::future<std::basic_string<char> >}'
In file included from swap.cpp:4:0:
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/future:111:11: error: declaration of 'std::__async_sfinae_helper<main()::<lambda()>, main()::<lambda()> >::type {aka class std::future<std::basic_string<char> >}'
swap.cpp:22:14: error: invalid use of incomplete type 'class std::future<std::basic_string<char> >'
In file included from swap.cpp:4:0:
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/future:111:11: error: declaration of 'class std::future<std::basic_string<char> >'
In file included from c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/bits/stl_algobase.h:68:0,
                 from c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/bits/char_traits.h:41,
                 from c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/ios:41,
                 from c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/ostream:40,
                 from c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/iostream:40,
                 from swap.cpp:1:
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/bits/stl_iterator.h: In instantiation of '__gnu_cxx::__normal_iterator<_Iterator, _Container>& __gnu_cxx::__normal_iterator<_Iterator, _Container>::operator++() [with _Iterator = std::future<std::basic_string<char> >*; _Container = std::vector<std::future<std::basic_string<char> > >; __gnu_cxx::__normal_iterator<_Iterator, _Container> = __gnu_cxx::__normal_iterator<std::future<std::basic_string<char> >*, std::vector<std::future<std::basic_string<char> > > >]':
swap.cpp:21:17:   required from here
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/bits/stl_iterator.h:750:2: error: cannot increment a pointer to incomplete type 'std::future<std::basic_string<char> >'
In file included from c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/vector:65:0,
                 from swap.cpp:2:
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/bits/stl_vector.h: In instantiation of 'std::_Vector_base<_Tp, _Alloc>::~_Vector_base() [with _Tp = std::future<std::basic_string<char> >; _Alloc = std::allocator<std::future<std::basic_string<char> > >]':
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/bits/stl_vector.h:247:15:   required from 'std::vector<_Tp, _Alloc>::vector() [with _Tp = std::future<std::basic_string<char> >; _Alloc = std::allocator<std::future<std::basic_string<char> > >]'
swap.cpp:15:26:   required from here
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/bits/stl_vector.h:161:9: error: invalid use of incomplete type 'class std::future<std::basic_string<char> >'
In file included from swap.cpp:4:0:
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/future:111:11: error: declaration of 'class std::future<std::basic_string<char> >'
In file included from c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/vector:63:0,
                 from swap.cpp:2:
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/bits/stl_construct.h: In instantiation of 'void std::_Destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = std::future<std::basic_string<char> >*]':
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/bits/stl_construct.h:155:7:   required from 'void std::_Destroy(_ForwardIterator, _ForwardIterator, std::allocator<_T2>&) [with _ForwardIterator = std::future<std::basic_string<char> >*; _Tp = std::future<std::basic_string<char> >]'
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/bits/stl_vector.h:403:9:   required from 'std::vector<_Tp, _Alloc>::~vector() [with _Tp = std::future<std::basic_string<char> >; _Alloc = std::allocator<std::future<std::basic_string<char> > >]'
swap.cpp:15:26:   required from here
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/bits/stl_construct.h:128:7: error: invalid use of incomplete type '_Value_type {aka class std::future<std::basic_string<char> >}'
In file included from swap.cpp:4:0:
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/future:111:11: error: declaration of '_Value_type {aka class std::future<std::basic_string<char> >}'
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/future: At global scope:
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/future:187:5: error: 'typename std::__async_sfinae_helper<typename std::decay<_Func>::type, _Fn, _Args ...>::type std::async(_Fn&&, _Args&& ...) [with _Fn = main()::<lambda()>; _Args = {}; typename std::__async_sfinae_helper<typename std::decay<_Func>::type, _Fn, _Args ...>::type = std::future<std::basic_string<char> >]', declared using local type 'main()::<lambda()>', is used but never defined [-fpermissive]
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/future:187:5: error: 'typename std::__async_sfinae_helper<typename std::decay<_Func>::type, _Fn, _Args ...>::type std::async(_Fn&&, _Args&& ...) [with _Fn = main()::<lambda()>; _Args = {}; typename std::__async_sfinae_helper<typename std::decay<_Func>::type, _Fn, _Args ...>::type = std::future<std::basic_string<char> >]', declared using local type 'main()::<lambda()>', is used but never defined [-fpermissive]
c:mingw64in../lib/gcc/x86_64-w64-mingw32/4.7.0/include/c++/future:187:5: error: 'typename std::__async_sfinae_helper<typename std::decay<_Func>::type, _Fn, _Args ...>::type std::async(_Fn&&, _Args&& ...) [with _Fn = main()::<lambda()>; _Args = {}; typename std::__async_sfinae_helper<typename std::decay<_Func>::type, _Fn, _Args ...>::type = std::future<std::basic_string<char> >]', declared using local type 'main()::<lambda()>', is used but never defined [-fpermissive]

我在 Windows 中使用 GCC 4.7.

I'm using GCC 4.7 in windows.

$ g++ -v
Using built-in specs.
COLLECT_GCC=c:mingw64inx86_64-w64-mingw32-g++.exe
COLLECT_LTO_WRAPPER=c:/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/4.7.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-4.7.0/configure --build=x86_64-w64-mingw32 --enable-targets=all --disable-multilib --enable-64bit --prefix=/mingw64 --with-sysroot=/mingw64 --disable-shared --enable-static --disable-nls --enable-version-specific-runtime-libs --disable-win32-registry --without-dwarf2 --enable-sjlj-exceptions --enable-fully-dynamic-string --enable-languages=c,ada,lto,c++,objc,obj-c++,fortran --enable-libgomp --enable-lto --enable-libssp -enable-gnattools --disable-bootstrap --with-gcc --with-gnu-as --with-gnu-ld --with-stabs --enable-interwork --with-mpfr-include=/home/beta/gcc-build/../gcc-4.7.0/mpfr/src --with-mpfr-lib=/home/beta/gcc-build/mpfr/src/.libs
Thread model: win32
gcc version 4.7.0 (GCC)

推荐答案

也许因为我写了那段代码,我更容易理解,但没那么难,直接看错误输出的第一行:

Maybe it's easier for me to interpret because I wrote that code, but it's not so hard, just look at the first line of the error output:

swap.cpp:22:14: error: invalid use of incomplete type 'class std::future<std::basic_string<char> >'

这告诉你 std::future 是一个不完整的类型,即它被声明但没有定义.下一行会准确地告诉您它的声明位置(然后所有其他错误都是由于尝试以不同方式使用该不完整类型而引起的.)

That's telling you that std::future is an incomplete type, i.e. it is declared but not defined. The next line tells you exactly where it's declared (then all the other errors are caused by trying to use that incomplete type in different ways.)

如果您查看 GCC 的 <future> 标头,您会看到类型声明在靠近顶部的位置,但是定义取决于此预处理器条件:

If you look in GCC's <future> header you'll see that the types are declared near the top, but then the definitions are dependent on this preprocessor condition:

#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) 
  && (ATOMIC_INT_LOCK_FREE > 1)

如果您使用这些宏编译一些简单的测试,您会发现 _GLIBCXX_HAS_GTHREADS 未定义,这是因为您的 gcc -v 显示

If you compile some simple tests with those macros you'll find out that _GLIBCXX_HAS_GTHREADS is not defined, and that's because your gcc -v shows

Thread model: win32

还没有人提供必要的代码来使 C++11 线程功能在 Windows 上运行.

No one has provided the necessary code to make the C++11 thread features work on Windows yet.

工作会更难,但实际上启用 并没有那么难> 但还没有人加紧进行这项工作.昨天我发布了一些关于如何为 win32 线程模型启用 C++11 线程功能的想法:http://gcc.gnu.org/ml/libstdc++/2012-05/msg00020.html

Making <future> work would be harder, but it's not actually that difficult to enable <thread> and <mutex> but no one has stepped up to do the work yet. Yesterday I posted some ideas for how to enable the C++11 thread features for the win32 thread model: http://gcc.gnu.org/ml/libstdc++/2012-05/msg00020.html

相关文章