显式专门化模板类成员函数具有不同的返回类型 [英] explicit specialization template class member function with different return type
问题描述
我试图将一些C ++代码从Windows移植到Solaris(Unix)。有一些模板代码需要更改。我使用Solaris的编译器CC,g ++应该有同样的问题。
I am trying to port some C++ code from Windows to Solaris(Unix). There are some template code need to be changed. I am using Solaris' compiler CC, g++ should have same issue.
我有一个特定的部分代码介绍一些麻烦。它们简化如下:
I have a particular part of code introduce some trouble. They are simplified as following:
#include <exception>
#include <cmath>
#include <string>
#include <iostream>
// define the "not implement" error
class tempException: public std::exception
{
public:
virtual const char* what() const throw()
{
return "not been implemented!";
}
} nondeferr;
// the template class
template <typename T>
class A
{
public:
template <typename Val>
Val getValue(T t) { throw nondeferr; }
template<>
double getValue(T t) { return exp( 1.5 * t ); } //Specialize the getValue for double type.
};
// test code
int main()
{
try
{
A<int> testA;
std::cout << testA.getValue<double>(2) << std::endl;
std::cout << testA.getValue<std::string>(2) << std::endl;
}
catch (tempException& e)
{
std::cout << e.what() << std::endl;
}
return 0;
}
要在UNIX中编译此示例代码,编译错误将作为显式
To compile this sample code in UNIX, the compilation error comes out as the explicit specialization cannot be in the class A scope.
这里getValue函数只不同于返回类型,所以我们不能使用重载方式修改它。
Here the getValue function only different from the return type, so we cannot modify it using the overload way.
由于某种原因,用简单的模板变量T将类A改为具有双模板变量T的类A,不允许Val。当我们尝试使用这个基本类时,它将引入很多变化。
And for some reason, change class A with simple template variable T to class A with double template variables T and Val is not allowed. It will introduce a lots of changes when we try to use this basic class.
我可以知道是否有任何解决方案?我现在删除getValue函数,将其替换为getDoubleValue ...但是这不太好。
May I know if there is any solution? I am currently remove the getValue function, replace it as getDoubleValue... But that is not so good too.
那些有兴趣的人,现在类A看起来像这样:
For those who interested, now the class A looks like this:
template <typename T>
class A
{
public:
// the Get Value we want
template <typename R>
R getValue(T t) { return get_value_impl<R>::apply(*this, t); }
// the general get value struct
template<typename R, typename = void>
struct get_value_impl
{
static R apply(A a, T t) { throw nondeferr; }
};
// partial specialization, which is allowed in std C++
template <typename S>
struct get_value_impl<double, S>
{
static double apply(A a, T t) { return exp( 1.5 * t ); }
};
};
后面的逻辑是标准中不允许的显式特化。但是,允许部分特化。感谢Anycorn再次获得灿烂的解决方案。
The logic behind is explicit specialization is not allowed in standard. However, partial specialization is allowed. Thanks Anycorn again for the splendid solution.
推荐答案
// the template class
template <typename T>
class A {
template<>
double getValue(T t) { return exp( 1.5 * t ); }
};
这是标准不允许的。
do:
template <typename T>
class A {
template<class R>
R getValue(T t) { return get_value_impl<double>::apply(*this, t); }
template<class R, class = void>
struct get_value_impl; // specialize this
};
这篇关于显式专门化模板类成员函数具有不同的返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!