创建 std::promise<std::tuple<T>> 时出现错误 C2512(仅限 Visual Studio)

Posted

技术标签:

【中文标题】创建 std::promise<std::tuple<T>> 时出现错误 C2512(仅限 Visual Studio)【英文标题】:Error C2512 when creating a std::promise<std::tuple<T>> (Visual Studio-only) 【发布时间】:2021-09-22 19:09:06 【问题描述】:

在创建类型 (T) 没有默认构造函数的 std::promise&lt;std::tuple&lt;T&gt;&gt; 时遇到错误(仅限 Visual Studio)。

我创建了一个派生示例来突出这个问题。

#include <future>
#include <tuple>

class Foo 
public:
    Foo() = delete;

    Foo(int value) :
        mValue value  

    

private:
    int mValue;
;

int main()

    std::promise<std::tuple<Foo>> p;

1>------ Build started: Project: ConsoleApplication1, Configuration: Debug Win32 ------
1>ConsoleApplication1.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\future(206): error C2512: 'std::tuple<Foo>::tuple': no appropriate default constructor available
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\future(203): message : while compiling class template member function 'std::_Associated_state<_Ty>::_Associated_state(std::_Deleter_base<_Ty> *)'
1>        with
1>        [
1>            _Ty=std::tuple<Foo>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\future(1143): message : see reference to function template instantiation 'std::_Associated_state<_Ty>::_Associated_state(std::_Deleter_base<_Ty> *)' being compiled
1>        with
1>        [
1>            _Ty=std::tuple<Foo>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\future(1143): message : see reference to class template instantiation 'std::_Associated_state<_Ty>' being compiled
1>        with
1>        [
1>            _Ty=std::tuple<Foo>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\future(1143): message : while compiling class template member function 'std::promise<std::tuple<Foo>>::promise(void)'
1>C:\Users\Quenton Jones\source\repos\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cpp(22): message : see reference to function template instantiation 'std::promise<std::tuple<Foo>>::promise(void)' being compiled
1>C:\Users\Quenton Jones\source\repos\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cpp(22): message : see reference to class template instantiation 'std::promise<std::tuple<Foo>>' being compiled
1>Done building project "ConsoleApplication1.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

使用clang编译时没有问题。

为什么 Visual Studio 要求 T 具有默认构造函数?

【问题讨论】:

known issue - We’ve investigated this issue and found that fixing it will break our ABI. To preserve binary compatibility, we don’t allow ABI breakages within the current release of the library. 【参考方案1】:

为了解决这个已知问题,我执行了以下操作:

class Foo 
public:
#if _WIN32
    Foo() 
        throw std::exception("Invalid Constructor");
    
#else
    Foo() = delete;
#endif

    Foo(int value) :
        mValue value  

    

private:
    int mValue;
;

【讨论】:

【参考方案2】:

错误 C2512 的常见原因是当您定义一个带参数的类或结构构造函数时,然后您尝试声明一个不带任何参数的类或结构的实例。有关详细信息,请参阅此document。

还有一点,目前std::promise不能用非默认可构造类型编译。使用#if#else也是一种方式。

【讨论】:

以上是关于创建 std::promise<std::tuple<T>> 时出现错误 C2512(仅限 Visual Studio)的主要内容,如果未能解决你的问题,请参考以下文章

[C++11 多线程异步] --- std::promise/std::future

带有 std::promise 的 C++11 分段错误

[C++11 多线程异步] --- std::promise/std::future

[C++11 多线程异步] --- std::promise/std::future

std::future, std::async, std::promise

std::future, std::async, std::promise