[英]VS2013 Variadic template compilation error
The code below (apologies for the length of it, but it's the only way I found to reproduce the error) fails to compile using VS2013.下面的代码(为它的长度道歉,但这是我发现重现错误的唯一方法)无法使用 VS2013 进行编译。 It seems to have something to do with expanding an empty parameter pack.它似乎与扩展空参数包有关。 However, when I remove any of the three lines in main(), the compilation error goes away.但是,当我删除 main() 中的三行中的任何一行时,编译错误就会消失。 This leads me to believe it is probably a bug - especially also because IDEone handles it fine :P这让我相信这可能是一个错误 - 特别是因为IDEone处理得很好:P
The compilation errors, line 28 is the one with using tuple_t = std::tuple< typename remove_const_and_reference< A >::type... >;
编译错误,第 28 行是using tuple_t = std::tuple< typename remove_const_and_reference< A >::type... >;
: :
(28): error C3548: 'A' : parameter pack cannot be used in this context
(19): see reference to function template instantiation 'void A::CallCore<Ret,>(Ret (__cdecl *)(void))' being compiled
with
[
Ret=Foo *
]
(50): see reference to function template instantiation 'void A::Call<T*,>(Ret (__cdecl *)(void))' being compiled
with
[
T=Foo,Ret=Foo *
]
(77): see reference to function template instantiation 'void B::RegisterConstructor<Foo,>(void)' being compiled
(28): error C2976: 'remove_const_and_reference' : too few template arguments
(28): error C2955: 'remove_const_and_reference' : use of class template requires template argument list
(28): error C2039: 'type' : is not a member of 'remove_const_and_reference'
(28): error C2146: syntax error : missing ',' before identifier 'type'
(28): error C3546: '...' : there are no parameter packs available to expand
(28): error C2065: 'type' : undeclared identifier
(28): error C3544: '_Types': parameter pack expects a type template argument
The question: I'm looking for a workaround and some insight into why there could be a problem?问题:我正在寻找一种解决方法并深入了解为什么会出现问题?
Code:代码:
#include <tuple>
#include <type_traits>
template< class T, class U = typename std::remove_cv< typename std::remove_reference< T >::type >::type >
struct remove_const_and_reference : remove_const_and_reference< U >
{
};
template< class T >
struct remove_const_and_reference< T, T >
{
typedef T type;
};
class A
{
public:
template< class Ret, class... Args >
void Call( Ret f( Args... ) ) { CallCore( f ); }
template< class Ret, class Obj, class... Args >
void Call( Ret( Obj::*f )( Args...) ) { CallCore( f ); }
private:
template< class Ret, class... Args >
void CallCore( Ret f( Args... ) )
{
using tuple_t = std::tuple< typename remove_const_and_reference< Args >::type... >;
}
template< class Ret, class Obj, class... Args >
void CallCore( Ret( Obj::*f )( Args...) )
{
using tuple_t = std::tuple< typename remove_const_and_reference< Args >::type... >;
}
};
template< class T, class... Args >
T* New( Args&&... args )
{
return new T( std::forward< Args >( args )... );
}
class B
{
public:
template< class T, class... Args >
void RegisterConstructor()
{
a.Call< T* >( New< T, Args... > );
}
template< class Fun >
void Register( Fun f )
{
a.Call( f );
}
private:
A a;
};
struct Foo
{
Foo(){}
~Foo(){}
void FunA( int ){}
};
void FunB( int ){}
int main()
{
B().Register( FunB );
B().Register( &Foo::FunA );
B().RegisterConstructor< Foo >();
}
To make it working in VS2013:要使其在 VS2013 中工作:
1. A
names your class, you should not use template <class A>
within class A
's scope. 1. A
为您的类命名,您不应在class A
的范围内使用template <class A>
。 Rename your parameter pack into let's say Args
:将您的参数包重命名为Args
:
template< class Ret, class Obj, class... Args > // << Use Args name, not A !
void CallCore( Ret( Obj::*f )( Args...) )
{
using tuple_t = std::tuple< typename remove_const_and_reference< Args >::type... >;
}
2.I don't get you struct (why it inherits itself?), change it to: 2.我不明白你的结构(为什么它继承自己?),将其更改为:
template <typename T>
struct remove_const_and_reference
{
using type = typename std::remove_cv< typename std::remove_reference< T >::type >::type;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.