使用VC 15.4.0,std :: function赋值生成C2679(用15.3.5编译) [英] With VC 15.4.0, std::function assignment produces C2679 (compiled with 15.3.5)
问题描述
以下代码使用VC 15.3.5编译得很好:
The following code compiles just fine with VC 15.3.5:
#include <Windows.h>
#include <string>
#include <memory>
#include <optional>
#include <functional>
class TypeDictionary;
class IStructureField {};
using FieldFactory = std::function<std::unique_ptr<IStructureField>(TypeDictionary& dict, LPCSTR szName, std::optional<ULONG> ulOffset, std::optional<std::string> strFieldType, std::optional<ULONG> ulFieldSize)>;
int main()
{
FieldFactory ff;
ff = [](TypeDictionary& dict, LPCSTR szName, std::optional<ULONG> ulOffset, std::optional<std::string> szFieldType, std::optional<ULONG> ulFieldSize) -> std::unique_ptr<IStructureField> {
return std::unique_ptr<IStructureField>();
};
return 0;
}
它使用15.4.0生成以下错误消息:
It produces the following error message with 15.4.0:
1>f:\projects\fullpath\fullpath\fullpath.cpp(22): error C2679: binary '=': no operator found which takes a right-hand operand of type 'main::<lambda_36489dce1cc59e5a8de4329a29806b5a>' (or there is no acceptable conversion)
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.11.25503\include\functional(656): note: could be 'std::function<std::unique_ptr<IStructureField,std::default_delete<_Ty>> (TypeDictionary &,LPCSTR,std::optional<ULONG>,std::optional<std::string>,std::optional<ULONG>)> &std::function<std::unique_ptr<_Ty,std::default_delete<_Ty>> (TypeDictionary &,LPCSTR,std::optional<ULONG>,std::optional<std::string>,std::optional<ULONG>)>::operator =(std::nullptr_t) noexcept'
1> with
1> [
1> _Ty=IStructureField
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.11.25503\include\functional(629): note: or 'std::function<std::unique_ptr<IStructureField,std::default_delete<_Ty>> (TypeDictionary &,LPCSTR,std::optional<ULONG>,std::optional<std::string>,std::optional<ULONG>)> &std::function<std::unique_ptr<_Ty,std::default_delete<_Ty>> (TypeDictionary &,LPCSTR,std::optional<ULONG>,std::optional<std::string>,std::optional<ULONG>)>::operator =(std::function<std::unique_ptr<_Ty,std::default_delete<_Ty>> (TypeDictionary &,LPCSTR,std::optional<ULONG>,std::optional<std::string>,std::optional<ULONG>)> &&)'
1> with
1> [
1> _Ty=IStructureField
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.11.25503\include\functional(612): note: or 'std::function<std::unique_ptr<IStructureField,std::default_delete<_Ty>> (TypeDictionary &,LPCSTR,std::optional<ULONG>,std::optional<std::string>,std::optional<ULONG>)> &std::function<std::unique_ptr<_Ty,std::default_delete<_Ty>> (TypeDictionary &,LPCSTR,std::optional<ULONG>,std::optional<std::string>,std::optional<ULONG>)>::operator =(const std::function<std::unique_ptr<_Ty,std::default_delete<_Ty>> (TypeDictionary &,LPCSTR,std::optional<ULONG>,std::optional<std::string>,std::optional<ULONG>)> &)'
1> with
1> [
1> _Ty=IStructureField
1> ]
1>f:\projects\fullpath\fullpath\fullpath.cpp(22): note: while trying to match the argument list '(FieldFactory, main::<lambda_36489dce1cc59e5a8de4329a29806b5a>)'
1>Done building project "FullPath.vcxproj" -- FAILED.
正如我在cppcon上看到的那样(Stephan的演讲),在< functional> $上做了很多工作c $ c> ......这可能是相关的吗?我犯了什么错误?
As I saw on cppcon (Stephan's talk), a lot of work has been done on <functional>
... Could this be related? Any mistake I made?
解决方法也没关系。
推荐答案
我想知道是否如果你真的定义了TypeDictionary,而不是只是向前声明它,它会工作。
I wonder whether it would work if you actually define TypeDictionary, rather than just forward-declaring it.
我的猜测是,较新的编译器实现了规范的这一部分(
http://en.cppreference.com/w/cpp/utility/functional/function/ operator%3D ):
My guess is, the newer compiler implements this part of the spec ( http://en.cppreference.com/w/cpp/utility/functional/function/operator%3D ):
"此运算符不参与重载决策,除非f对于参数类型Args可调用并返回类型R.(因为C + +14)"
"This operator does not participate in overload resolution unless f is Callable for argument types Args... and return type R. (since C++14)"
当尝试确定lambda是否可调用时失败,因为其中一个参数属于不完整类型。
And it fails when trying to determine whether the lambda is callable, because one of the parameters is of an incomplete type.
错误spew列出了operator =编译器尝试过的所有重载,并且未提及您要使用的模板化的重载。这表明它已经从之前设置的过载中消除了。
The error spew lists all the overloads of operator= the compiler has tried, and the templated one you want to use is not mentioned. Which suggests that it got eliminated from the overload set earlier.
现在,我不确定它是否真的应该起作用。这需要通过"可调用"仔细解析标准的含义,这比我现在可以召唤的时间和耐心要多。
Now, I'm not sure whether or not it's actually supposed to work. That would require a careful parsing of what the standard means by "Callable", which would take more time and patience than I can summon at the moment.
这篇关于使用VC 15.4.0,std :: function赋值生成C2679(用15.3.5编译)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!