C++模板类中模板函数的特化
用于专门化模板类内的模板函数的 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;
}
我已经尝试猜测专业化的正确语法至少一个小时了,但无法弄清楚任何可以编译的内容。任何帮助将不胜感激!
What is the C++ syntax for specializing a template function that's inside a template class? For example, consider that I have the following two classes and their usage. I would like to be able to provide specialized implementations of the method X::getAThing() for different types. E.g.: int, std::string, arbitrary pointer or class, etc.
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;
}
I've been trying to guess at the correct syntax for the specialization for at least an hour, and can't figure anything out that will compile. Any help would be greatly appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
AFAIK(标准专家可以纠正我),如果不专门化类本身,您就无法专门化类模板的模板化函数......
即我认为以下内容可行:
AFAIK (and the standards experts can correct me), you cannot specialize a templated function of a class template without specializing the class itself...
i.e. the following I think will work:
C++ 没有函数模板的部分特化的概念。但是,您可以通过函数重载获得与完全专业化相同的效果。
我假设你有这样的东西,这确实是唯一的方法之一。
在这种情况下,您可以通过声明具有所需类型的普通成员函数来专门化“myFunction()”。 C++的函数重载规则应该给你你想要的,例如
编译器将在适当的地方使用“std::string”函数,并且可能根本不会使用内部模板。
C++ has no concept of partial specialization for function templates. However, you can get the same effect as full specialization through function overloading.
I am assuming you have something like this, which is really one of the only ways to do it.
In this case, you specialize "myFunction()" by declaring ordinary member functions with the desired type. C++'s function overloading rules should give you what you want, e.g.
The compiler will use the "std::string" function where appropriate, and may never use the inner template at all.
所以,我采取不同的方法来回答你的问题。我将从某种能满足您的要求并且有效的东西开始。然后也许我们可以弄清楚如何将其排列成更接近您真正想要的东西:
这是另一个可行的想法,虽然不完全是您想要的,但更接近。我想你自己已经想到了。它使用类型推导的方式也相当丑陋。
我建议在半私有实用程序命名空间中声明
getThingFunctor
和FriendlyGetThing
。So, I'm taking a different approach to answering your question. I'm going to start from something that sort of does what you want, and works. And then maybe we can figure out how to permute it into something closer to what you really want:
Here is another idea that sort of works, and isn't exactly what you want, but is closer. I think you've thought of it yourself. It's also rather ugly in the way it uses type deduction.
I would recommend declaring
getThingFunctor
andfriendlyGetThing
in a semi-private utility namespace.对于好奇的人来说,这可能是我将在自己的代码中采用的解决方案。这与 Omnifarious 的答案略有不同,无需额外的课程。我仍然支持 Omnifarious,因为他做了大部分的跑腿工作:
For the curious, this is probably the solution I'm going to go with in my own code. This is a slight variation on Omnifarious's answer, that eliminates the need for an extra class. I still give props to Omnifarious, as he did most of the leg work:
尝试
这个仍然无法编译,但它比你的更接近。
我认为你不能让全体成员专业化。您必须先指定类模板的特定特化,然后才能开始特化其成员。
Try
This still doesn't compile, but it's closer than you had.
I think you can't specialize members en masse. You have to specify a particular specialization of the class template before you can start specializing its members.
这是迄今为止我见过的最简单、最容易的方法:
Here's the simplest, easiest way I've seen so far to do this: