我正在尝试创建一个函数:
template <typename T>
void doIt( T*& p )
{
if ( !p ) { return; }
T& ref = *p;
getClassName( ref );
}
其中行为根据p
传入的类型而有所不同。特别是,被getClassName
调用的版本应该取决于p
. 在以下示例中,我可以成功调用:
doIt<myClass1>( myClass1*& )
doIt<myClass1<int> >( myClass1*& )
doIt<myClass2>( myClass2*& )
doIt<myClass2<int> >( myClass2*& )
但是当我打电话时它失败了:
doIt< std::vector<int, std::allocator<int> > >( std::vector<int, std::allocator<int>>*& )
出现错误:
a.cxx: In function ‘void doIt(T*&) [with T = std::vector<int, std::allocator<int> >]’:
ba.cxx:87: instantiated from here
a.cxx:33: error: invalid initialization of reference of type ‘MyClass1&’ from expression of type ‘std::vector<int, std::allocator<int> >’
a.cxx:16: error: in passing argument 1 of ‘const char* getClassName(MyClass1&)’
(GCC 4.2.4)。
如果我移动以下声明:
template<typename T, typename A>
char const* getClassName( std::vector<T,A>& ) { printf("std::vector<T,A>\n"); return NULL; }
在 doIt 之前 - 然后它编译。所以,
- 为什么需要
getClassName( std::vector<T,A>& )
出现在之前doIt
而不是getClassName( MyClass2T<T>& )
- 我该怎么做才能
doIt
独立std::vector
?(我希望能够放置doIt
在自己的标题中,而不必了解std::vector
或任何专业化,这将是用户定义的)。
.
#include <stdio.h>
#include <assert.h>
#include <vector>
//template<typename T>
//char const* getClassName( T& );
//template<typename T, typename A>
////char const* getClassName( std::vector<T,A>& ) { printf("std::vector<T,A>\n"); return NULL; }
#if 1
// --------- MyClass2
struct MyClass1
{};
char const* getClassName( MyClass1& ) { printf("MyClass1\n"); return NULL; }
// --------- MyClass1T
template< typename T>
struct MyClass1T
{};
template<typename T>
char const* getClassName( MyClass1T<T>& ) { printf("MyClass1T<T>\n"); return NULL; }
#endif
template <typename T>
void doIt( T*& p )
{
if ( !p ) { return; }
T& ref = *p;
getClassName( ref );
}
// --------- MyClass2
struct MyClass2
{};
// declared after doIt, OK.
char const* getClassName( MyClass2& ) { printf("MyClass2\n"); return NULL; }
// --------- MyClass2T
template< typename T>
struct MyClass2T
{};
// declared after doIt, OK.
template<typename T>
char const* getClassName( MyClass2T<T>& ) { printf("MyClass2T<T>\n"); return NULL; }
template<typename T, typename A>
char const* getClassName( std::vector<T,A>& ) { printf("std::vector<T,A>\n"); return NULL; }
void test()
{
#if 1
MyClass1 mc1;
MyClass1* mc1p = &mc1;
doIt( mc1p );
MyClass2 mc2;
MyClass2* mc2p = &mc2;
doIt( mc2p );
MyClass1T<int> mc1t;
MyClass1T<int>* mc1tp = &mc1t;
doIt( mc1tp );
MyClass2T<int> mc2t;
MyClass2T<int>* mc2tp = &mc2t;
doIt( mc2tp );
// Nested templates are OK.
MyClass2T<MyClass1> mc2t2;
MyClass2T<MyClass1>* mc2tp2 = &mc2t2;
doIt( mc2tp2 );
#endif
#if 1
std::vector<int> v;
std::vector<int>* vp = &v;
doIt( vp ); // FAIL!
#endif
}