我想专门化一个函数模板,以便返回类型根据模板参数的类型而变化。
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() { ... }
这可能吗?我无法使用 C++11。
由于特化必须与返回类型上的基本模板一致,因此您可以通过添加“返回类型特征”来实现这一点,这是一个可以特化并从中绘制真实返回类型的结构:
// 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>();
请注意,您可能想坚持以下内容,因此您只需更新
item_return
专业化中的返回类型。
template<>
item_return<float>::type foo<float>(){ ... }
// note: No `typename` needed, because `float` is not a dependent type
您可以像这样进行模板专业化:
template<typename T>
T item() {
return T();
}
template<>
float item<float>() {
return 1.0f;
}
在工作类中完成所有专业化,并使用一个简单的函数作为将隐式专业化的包装器。
#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";
}
在此示例中,
unsigned char
的特化导致它被转换为int
,以便cout
将其显示为数字而不是字符,生成以下输出...
a=A, b=66
也许你可以使用以下技巧。鉴于这些简单的类型特征:
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; };
您可以编写您的类和专门的成员函数,如下所示:
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; }
简单测试程序(使用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, "!");
}
这是一个实例。
您好,我尝试使用模板专门化来返回基元以及 std::string 数据的参数值,但这样做时我遇到了很多未解决的外部重新定义类型的错误。 因此,如果有人遇到这样的情况,当他/她想要返回不同的数据类型(包括字符串)时,他/她可以使用如下所示的内容, 注意:模板函数必须是头文件(*.h)的一部分... 所以我们在这里使用模板专业化字符串数据类型...... 在类内部作为内联成员,我们必须使用模板专用方法,并且在同一个文件中我们也可以定义模板。
class ConfigFileParser
{
public:
bool ParseConfigFile(const std::string& file_name);
template <typename T>
T GetParameterValue(const std::string key);
template <>
std::string GetParameterValue<std::string>(const std::string key)
{
std::string param_val = "";
//do logical operation here...
return param_val;
}
private:
// private functions...
// private data...
};
template <typename T>
T ConfigFileParser::GetParameterValue(const std::string key)
{
T param_val = 0;
std::stringstream ss;
std::string val_str;
// do some operation here...
ss << val_str.c_str();
ss >> param_val;
return param_val;
}
在 C++23 的帮助下,您可以用更少的代码来完成:
#include <type_traits>
template<typename T>
std::type_identity_t<T> bar();
template<>
std::type_identity_t<float> bar<float>() {return {}; }
template<>
std::type_identity_t<int> bar<int>() {return {}; }