C++ C2516在Visual Studio 2013中从lambda继承时出错 #包括 #包括 #包括 使用名称空间std; 模板 类onexiimpl:private T { 公众: 模板 onexitempl(Y&&todo):T(std::forward(todo)),_doIt(true){ OnExitImpl(OnExitImpl&&other):T(std::move(static_cast(other)),_doIt(other._doIt) { 其他。_doIt=false; } ~onexiimpl() { 如果(_doIt) { (*此项)(); } } 作废取消() { _doIt=false; } OnExitImpl&运算符=(OnExitImpl&其他) { this->T::operator=(std::move(static_cast(other)); _doIt=其他; 其他。_doIt=false; } 私人: 布尔多伊特; }; 模板 OnExitImpl OnExit(T动作) { 返回OnExitImpl(std::move(action)); } int-fetch多线程(int-stmt) { auto-onExit=onExit([&](){cout
这是一个我相信以前遇到过的VC++错误(如此)。最小复制示例:C++ C2516在Visual Studio 2013中从lambda继承时出错 #包括 #包括 #包括 使用名称空间std; 模板 类onexiimpl:private T { 公众: 模板 onexitempl(Y&&todo):T(std::forward(todo)),_doIt(true){ OnExitImpl(OnExitImpl&&other):T(std::move(static_cast(other)),_doIt(other._doIt) { 其他。_doIt=false; } ~onexiimpl() { 如果(_doIt) { (*此项)(); } } 作废取消() { _doIt=false; } OnExitImpl&运算符=(OnExitImpl&其他) { this->T::operator=(std::move(static_cast(other)); _doIt=其他; 其他。_doIt=false; } 私人: 布尔多伊特; }; 模板 OnExitImpl OnExit(T动作) { 返回OnExitImpl(std::move(action)); } int-fetch多线程(int-stmt) { auto-onExit=onExit([&](){cout,c++,templates,c++11,visual-studio-2013,C++,Templates,C++11,Visual Studio 2013,这是一个我相信以前遇到过的VC++错误(如此)。最小复制示例: template <typename Ret> struct FnPtrWrapper { FnPtrWrapper(Ret (*fn)(void)) : _fn(fn) { assert(fn); } Ret operator()() const { return (*_fn)(); } private: Ret (*_fn)(
template <typename Ret>
struct FnPtrWrapper
{
FnPtrWrapper(Ret (*fn)(void)) : _fn(fn)
{
assert(fn);
}
Ret operator()() const
{
return (*_fn)();
}
private:
Ret (*_fn)(void);
};
template <typename Ret>
OnExitImpl<FnPtrWrapper<Ret>> OnExit(Ret(*fn)(void))
{
return OnExitImpl<FnPtrWrapper<Ret>>(fn);
}
#包括
模板
结构B{static_assert(std::is_class::value,“T不是类”);};//(2)
int main()
{
[]{
自动a=[]{};
静态断言(std::is_class::value,“非类”);/(1)
B B;
}();
}
请注意,代码必须在外部lambda中才能发生错误。当(1)成功时,
b
的声明导致(2)失败
source_file.cpp(4):错误C2338:T不是类source_file.cpp(11):参见正在编译的类模板“
B
”的参考
这表示模板参数
decltype(a)
表示函数类型的指针,同时也表示类类型。您需要为std::forward
指定模板参数,请参见此-如果您进行了更改,您的代码将编译,但在运行时崩溃,因为编写时,可连接线程的析构函数被调用-谢谢,它现在可以在Ideone上编译,但仍然可以visual studio不走运。我不太在乎崩溃,因为这是另一个程序的简化。@Columbo-我希望不会,因为这会严重阻碍C++11中lambdas的重点。@Bwmat哎哟。我甚至没有读到错误消息。你应该,这会让人开怀大笑
1>Source.cpp(9): error C2516: 'T' : is not a legal base class
1> Source.cpp(55) : see declaration of 'T'
1> Source.cpp(55) : see reference to class template instantiation 'OnExitImpl<void (__cdecl *)(void)>' being compiled
template <typename Ret>
struct FnPtrWrapper
{
FnPtrWrapper(Ret (*fn)(void)) : _fn(fn)
{
assert(fn);
}
Ret operator()() const
{
return (*_fn)();
}
private:
Ret (*_fn)(void);
};
template <typename Ret>
OnExitImpl<FnPtrWrapper<Ret>> OnExit(Ret(*fn)(void))
{
return OnExitImpl<FnPtrWrapper<Ret>>(fn);
}
#include <type_traits>
template <typename T>
struct B { static_assert(std::is_class<T>::value, "T not a class"); }; // (2)
int main()
{
[]{
auto a = []{};
static_assert( std::is_class<decltype(a)>::value, "Not a class" ); // (1)
B<decltype(a)> b;
}();
}