C++ 在函数模板特化中覆盖返回类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15911890/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Overriding return type in function template specialization
提问by M. Dudley
I would like to specialize a function template such that the return type changes depending on the type of the template argument.
我想专门化一个函数模板,以便返回类型根据模板参数的类型而变化。
class ReturnTypeSpecialization
{
public:
template<typename T>
T Item();
};
// Normally just return the template type
template<typename T>
T ReturnTypeSpecialization::Item() { ... }
// When a float is specified, return an int
// This doesn't work:
template<float>
int ReturnTypeSpecialization::Item() { ... }
Is this possible? I can't use C++11.
这可能吗?我不能使用 C++11。
回答by Xeo
Since the specialization has to agree with the base template on the return type, you can make it so by adding a "return type trait", a struct you can specialize and draw the true return type from:
由于特化必须与返回类型的基本模板一致,您可以通过添加“返回类型特征”来实现,您可以特化并从中绘制真正的返回类型的结构:
// in the normal case, just the identity
template<class T>
struct item_return{ typedef T type; };
template<class T>
typename item_return<T>::type item();
template<>
struct item_return<float>{ typedef int type; };
template<>
int item<float>();
Note that you might want to stick to the following, so you only need to update the return-type in the item_return
specialization.
请注意,您可能想坚持以下几点,因此您只需要更新item_return
专业化中的返回类型。
template<>
item_return<float>::type foo<float>(){ ... }
// note: No `typename` needed, because `float` is not a dependent type
回答by nobar
Do all of the specialization in a worker class and use a simple function as a wrapper that will be specialized implicitly.
在工作类中完成所有特化,并使用一个简单的函数作为隐式特化的包装器。
#include <iostream>
using std::cout;
// worker class -- return a reference to the given value
template< typename V > struct worker
{
typedef V const & type;
static type get( V const & v ) { return v; }
};
// worker class specialization -- convert 'unsigned char' to 'int'
template<> struct worker<unsigned char>
{
typedef int type;
static type get( unsigned char const & v ) { return v; }
};
// mapper function
template< typename V > typename worker<V>::type mapper( V const & v )
{
return worker<V>::get(v);
}
int main()
{
char a='A';
unsigned char b='B';
cout << "a=" << mapper(a) << ", b=" << mapper(b) << "\n";
}
In this example, the specialization of unsigned char
causes it to be converted to an int
so that cout
will display it as a number instead of as a character, generating the following output...
在这个例子中, 的特化unsigned char
导致它被转换为 anint
以便cout
将它显示为数字而不是字符,生成以下输出...
a=A, b=66
回答by Andy Prowl
Perhaps you could use the following hack. Given these simple type traits:
也许您可以使用以下技巧。鉴于这些简单的类型特征:
template<bool b, typename T, typename U>
struct conditional { typedef T type; };
template<typename T, typename U>
struct conditional<false, T, U> { typedef U type; };
template<typename T, typename U>
struct is_same { static const bool value = false; };
template<typename T>
struct is_same<T, T> { static const bool value = true; };
You could write your class and specialized member function as follows:
您可以按如下方式编写您的类和专门的成员函数:
class ReturnTypeSpecialization
{
public:
template<typename T>
typename conditional<is_same<T, float>::value, int, T>::type
Item();
};
// Normally just return the template type
template<typename T>
typename conditional<is_same<T, float>::value, int, T>::type
ReturnTypeSpecialization::Item() { return T(); }
// When a float is specified, return an int
template<>
int ReturnTypeSpecialization::Item<float>() { return 1.0f; }
Simple test program (uses C++11 just for verification):
简单的测试程序(仅使用 C++11 进行验证):
int main()
{
ReturnTypeSpecialization obj;
static_assert(std::is_same<decltype(obj.Item<bool>()), bool>::value, "!");
static_assert(std::is_same<decltype(obj.Item<float>()), int>::value, "!");
}
Here is a live example.
这是一个活生生的例子。
回答by Rapptz
You can do template specializations like so:
您可以像这样进行模板专业化:
template<typename T>
T item() {
return T();
}
template<>
float item<float>() {
return 1.0f;
}