请注意C 03是我真正需要的,但是对于knoledge,我也想在C11中看到一些更漂亮的实现.
我需要一个模板类
template <typename T> class A { private: T m_member; public: A(T _member); //... MORE STUFF void foo(T param); };
我需要:
1)如果A被编译成一个值类型(包括指针,它们本身是通过值传递的):
然后我需要A看起来像这样(完全像上面)
class A { private: T m_member; public: A(T _member); //... MORE STUFF void foo(T param); };
2)如果使用引用类型(例如int&)编译A:
然后我需要A看起来像这样:
class A{ private: T& m_member; public: A(T& _member); //... MORE STUFF void foo(T param);//still the same T,not T& };
如果我知道A只收到ints,那么我将能够使用专业化.
但A的用户可以使用任何类型:
main.cpp中
A<int> a1;//1st version A<int&> a2;//2nd version A<B> a3;//1st version A<B&> a4;//2nd version A<C*> a5;//1st version
解决方法
在这个线程
Specializing function template for reference types中看到(正确),这里建议的remove_reference将不起作用.它不会进入第二个实现EVER,因为编译器看到T&和T一样.
相反,您可以手动告诉编译器它正在处理引用类型,使用相同的专业技巧
template<typename T,bool isReference> class A { }; template<typename T> class A<T,false>{ private: T m_member; public: A(T _member); //... MORE STUFF void foo(T param); } ///////////////////////// template<typename T> class A<T,true>{ private: T& m_member; public: A(T& _member); //... MORE STUFF void foo(T param); }
如果你想提取一些类似的行为,并避免这个解决方案导致的代码重用,你可以很容易地将该行为提取到基类< T>,并且
template<typename T,bool isReference> class A : public BaseClass<T>{ }
等等.
用法就是
main.cpp中
A<int,false> a1;//1st version A<int&,true> a2;//2nd version A<B,false> a3;//1st version A<B&,true> a4;//2nd version A<C*,false> a5;//1st version,as pointers are value types