아래 코드 (길이에 대해서는 사과하겠습니다 만 오류를 재현하는 유일한 방법입니다)는 VS2013을 사용하여 컴파일되지 않습니다. 빈 매개 변수 팩을 확장하는 것과 관련이있는 것 같습니다. 그러나 을 제거하면 main()에서 세 줄 중이 나오기 때문에 컴파일 오류가 사라집니다.VS2013 Variadic 템플릿 컴파일 오류
(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
질문 : 내가 찾고 있어요
컴파일 오류, 라인 (28) using tuple_t = std::tuple< typename remove_const_and_reference<A>::type... >;
과 하나가 P : 특히도 IDEone 때문에 잘 그것을 처리 - 이것은 아마 버그가 있는게 틀림 없어 문제가 될 수있는 이유에 대한 해결 방법과 통찰력이 필요하십니까?
코드 :
1. A
이름 클래스, 당신은 class A
의 범위 내에서 template <class A>
를 사용하지 않아야합니다 :
#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>();
}
나쁜 생각, 하지만 문제가되지 않습니다. – stijn
@stijn : CallCore에서 A의 이름이 바뀌면 작동합니다. –
그것은 나를위한 것이 아닙니다. 모든 A를 Args로 이름을 바꾸더라도 문제가 남아 있습니다. 또한 afaik C++ 11 이름 분석 규칙은 A가 외부 클래스 A로 취급되어서는 안되지만 템플릿 인수 A로 취급되어야한다고 말합니다.이 경우 VS에는 문제가 없습니다. 어쨌든, 질문을 편집하여 이제는 명확성을위한 Args를 갖습니다. – stijn