Ogr*_*m33 29 c++ syntax templates template-specialization
什么是专门用于模板类中的模板函数的C++语法?例如,考虑我有以下两个类及其用法.我希望能够为不同类型提供方法X :: getAThing()的专门实现.例如:int,std :: string,任意指针或类等.
template <class c1> class X {
public:
template<typename returnT> returnT getAThing(std::string param);
static std::string getName();
private:
c1 theData;
};
// This works ok...
template <class c1> std::string X<c1>::getName() {
return c1::getName();
}
// This blows up with the error:
// error: prototype for 'int X<c1>::getAThing(std::string)' does not match any in class 'X<c1>'
template <class c1> template <typename returnT> int X<c1>::getAThing(std::string param) {
return getIntThing(param); // Some function that crunches on param and returns an int.
}
// More specialized definitions of getAThing() for other types/classes go here...
class Y {
public:
static std::string getName() { return "Y"; }
};
int main(int argc, char* argv[])
{
X<Y> tester;
int anIntThing = tester.getAThing<int>(std::string("param"));
cout << "Name: " << tester.getName() << endl;
cout << "An int thing: " << anIntThing << endl;
}
Run Code Online (Sandbox Code Playgroud)
我一直试图猜测专业化的正确语法至少一个小时,并且无法解决任何可编译的问题.任何帮助将不胜感激!
Nim*_*Nim 18
AFAIK(以及标准专家可以纠正我),你不能专门化类模板的模板化功能而不专门化类本身......
即以下我认为将起作用:
template <> template <> int X<Y>::getAThing<int>(std::string param) {
return getIntThing(param); // Some function that crunches on param and returns an int.
}
Run Code Online (Sandbox Code Playgroud)
小智 8
C++没有对函数模板进行部分特化的概念.但是,您可以通过函数重载获得与完全特化相同的效果.
我假设你有这样的东西,这实际上是唯一的方法之一.
template<class TYPE>
class MyInterface {
public:
template<class RETURN>
RETURN myFunction(RETURN& ref, ....);
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您通过声明具有所需类型的普通成员函数来专门化"myFunction()".C++的函数重载规则应该给你你想要的东西,例如
template<class TYPE>
class MyInterface {
public:
template<class RETURN>
RETURN myFunction(RETURN& ref, ....);
// String specialization
std::string myFunction(std::string& ref, ...);
};
Run Code Online (Sandbox Code Playgroud)
编译器将在适当的地方使用"std :: string"函数,并且可能永远不会使用内部模板.
所以,我采取了不同的方法来回答你的问题.我将从你想要的东西开始,并且有效.然后,也许我们可以弄清楚如何将它置于更接近你真正想要的东西:
#include <string>
#include <iostream>
int getIntThing(const ::std::string ¶m);
template <typename returnT>
returnT getThingFree(const ::std::string ¶m);
template <>
int getThingFree<int>(const ::std::string ¶m)
{
return getIntThing(param);
}
// More specialized definitions of getAThing() for other types/classes
// go here...
template <class c1> class X {
public:
template<typename returnT> returnT getAThing(std::string param);
static std::string getName();
private:
c1 theData;
};
// This works ok...
template <class c1> std::string X<c1>::getName() {
return c1::getName();
}
// This also works, but it would be nice if I could explicitly specialize
// this instead of having to explicitly specialize getThingFree.
template <class c1>
template <class RT>
RT X<c1>::getAThing(std::string param) {
// Some function that crunches on param and returns an RT.
// Gosh, wouldn't it be nice if I didn't have to redirect through
// this free function?
return getThingFree<RT>(param);
}
class Y {
public:
static std::string getName() { return "Y"; }
};
int main(int argc, char* argv[])
{
using ::std::cout;
X<Y> tester;
int anIntThing = tester.getAThing<int>(std::string("param"));
cout << "Name: " << tester.getName() << '\n';
cout << "An int thing: " << anIntThing << '\n';
}
Run Code Online (Sandbox Code Playgroud)
这是另一种有用的想法,并不是你想要的,但更接近.我想你自己已经想过了.它使用类型演绎的方式也相当丑陋.
#include <string>
#include <iostream>
template <class c1> class X;
int getIntThing(const ::std::string ¶m)
{
return param.size();
}
// You can partially specialize this, but only for the class, or the
// class and return type. You cannot partially specialize this for
// just the return type. OTOH, specializations will be able to access
// private or protected members of X<c1> as this class is declared a
// friend.
template <class c1>
class friendlyGetThing {
public:
template <typename return_t>
static return_t getThing(X<c1> &xthis, const ::std::string ¶m,
return_t *);
};
// This can be partially specialized on either class, return type, or
// both, but it cannot be declared a friend, so will have no access to
// private or protected members of X<c1>.
template <class c1, typename return_t>
class getThingFunctor {
public:
typedef return_t r_t;
return_t operator()(X<c1> &xthis, const ::std::string ¶m) {
return_t *fred = 0;
return friendlyGetThing<c1>::getThing(xthis, param, fred);
}
};
template <class c1> class X {
public:
friend class friendlyGetThing<c1>;
template<typename returnT> returnT getAThing(std::string param) {
return getThingFunctor<c1, returnT>()(*this, param);
}
static std::string getName();
private:
c1 theData;
};
// This works ok...
template <class c1> std::string X<c1>::getName() {
return c1::getName();
}
class Y {
public:
static std::string getName() { return "Y"; }
};
template <class c1>
class getThingFunctor<c1, int> {
public:
int operator()(X<c1> &xthis, const ::std::string ¶m) {
return getIntThing(param);
}
};
// More specialized definitions of getAThingFunctor for other types/classes
// go here...
int main(int argc, char* argv[])
{
using ::std::cout;
X<Y> tester;
int anIntThing = tester.getAThing<int>(std::string("param"));
cout << "Name: " << tester.getName() << '\n';
cout << "An int thing: " << anIntThing << '\n';
}
Run Code Online (Sandbox Code Playgroud)
我会建议宣布getThingFunctor和friendlyGetThing在半私营公用事业的命名空间.