当我尝试编译时:
#include <functional>
void f(std::function<void()> f)
{
}
void g()
{
f([](auto&&...){});
}
Run Code Online (Sandbox Code Playgroud)
在gcc 7.3上,我收到以下错误:
[x86-64 gcc 7.3#1]错误:无法将'
<lambda closure object>g()::<lambda(auto:1&&, ...)>{}'从'g()::<lambda(auto:1&&, ...)>' 转换为'std::function<void()>'
有人可以解释为什么这是无效的c ++?或者我应该提交错误报告?(MSVC 14接受并按照我的预期编译它.)
我认为这段代码是有效的C++.MSVC同意,但gcc似乎不同意.MSVC和我错了吗?(或者我应该输入略有不同的东西?)
#include <iostream>
#include <string>
#include <vector>
#include <functional>
template <typename T>
struct S
{
template <typename R>
void f(std::function<R(T)> fn)
{
auto p = &fn;
++p;
}
template <typename R>
void g(std::function<R(void)> fn)
{
auto p = &fn;
++p;
}
};
void f()
{
S<void> s;
auto p = &s;
++p;
}
int main()
{
f();
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
<source>: In instantiation of 'struct S<void>':
<source>:26:11: required from here
<source>:11:8: error: invalid parameter type 'void'
void f(std::function<R(T)> fn)
^
<source>:11:8: …Run Code Online (Sandbox Code Playgroud) 给出以下代码:
typename std::aligned_storage<sizeof(T), alignof(T)>::type storage_t;
//this moves the back of src to the back of dst:
void push_popped(std::list<storage_t> & dstLst, std::list<storage_t> & srcLst)
{
auto & src = srcLst.back();
dstLst.push_back(storage_t());
auto & dst = dstLst.back();
std::memcpy(&dst, &src, sizeof(T));
srcLst.pop_back();
}
Run Code Online (Sandbox Code Playgroud)
我知道这种方法通常不正确的3个原因(即使该方法避免了调用src->~T(),因此也避免了T对资源的重复声明)。
U*指向U同一对象的其他成员的类型的对象成员T存在,src并且T现在确实存在dst(这里提到了这些:http : //www.gamedev.net/topic/655730-c-stdmove-vs-stdmemcpy/#entry5148523。)
假设该T类型不是其内存地址为其状态(例如,std::mutex或std::condition_variable)的属性,那么这种方法是否仅有这些问题?还是还有其他可能出错的事情?我想对未知问题进行描述。
我想认为我开发了“对象重定位语义”,但是我不希望人们考虑其中是否有明显的漏洞。