C++ 如何专门化std::vector<;的模板成员函数;T>;
我需要用两种不同的方式定义get方法。一个用于简单类型T,一个用于std::vectorC++ 如何专门化std::vector<;的模板成员函数;T>;,c++,templates,C++,Templates,我需要用两种不同的方式定义get方法。一个用于简单类型T,一个用于std::vector template<typename T> const T& Parameters::get(const std::string& key) { Map::iterator i = params_.find(key); ... return boost::lexical_cast<T>(boost::get<std::string>(
template<typename T>
const T& Parameters::get(const std::string& key)
{
Map::iterator i = params_.find(key);
...
return boost::lexical_cast<T>(boost::get<std::string>(i->second));
...
}
模板
常量T和参数::get(常量std::字符串和键)
{
Map::iterator i=params_u.find(键);
...
返回boost::lexical_cast(boost::get(i->second));
...
}
如何将此方法专门化为std::vector。因此,代码应该如下所示:
template<typename T>
const T& Parameters::get(const std::string& key)
{
Map::iterator i = params_.find(key);
std::vector<std::string> temp = boost::get<std::vector<std::string> >(i->second)
std::vector<T> ret(temp.size());
for(int i=0; i<temp.size(); i++){
ret[i]=boost::lexical_cast<T>(temp[i]);
}
return ret;
}
模板
常量T和参数::get(常量std::字符串和键)
{
Map::iterator i=params_u.find(键);
std::vector temp=boost::get(i->second)
std::vector ret(temp.size());
对于(inti=0;iErm)来说,把它叫做别的东西
template<typename T>
const T& Parameters::getVector(const std::string& key)
{
Map::iterator i = params_.find(key);
std::vector<std::string> temp = boost::get<std::vector<std::string> >(i->second)
// T is already a vector
T ret; ret.reserve(temp.size());
for(int i=0; i<temp.size(); i++){
ret.push_back(boost::lexical_cast<typename T::value_type>(temp[i]));
}
return ret;
}
然后在您的方法中变成:
template<typename T>
const T& Parameters::get(const std::string& key)
{
return getter<T>()(key); // pass the structures getter needs?
}
模板
常量T和参数::get(常量std::字符串和键)
{
return getter()(key);//传递getter需要的结构?
}
不要专门化函数模板。
相反,使用重载。
编写一个函数模板get_impl
来处理一般情况,并重载(而不是专门化)此模板来处理特定情况,然后调用get_impl
fromget
,如下所示:
template<typename T>
const T& Parameters::get(const std::string& key)
{
//read the explanation at the bottom for the second argument!
return get_impl(key, static_cast<T*>(0) );
}
模板
常量T和参数::get(常量std::字符串和键)
{
//请阅读第二个论点底部的解释!
返回get_impl(key,static_cast(0));
}
下面是实际的实现
//general case
template<typename T>
const T& Parameters::get_impl(const std::string& key, T*)
{
Map::iterator i = params_.find(key);
return boost::lexical_cast<T>(boost::get<std::string>(i->second));
}
//this is overload - not specialization
template<typename T>
const std::vector<T>& Parameters::get_impl(const std::string& key, std::vector<T> *)
{
//vector specific code
}
//一般情况
模板
常量T和参数::get_impl(常量std::字符串和键,T*)
{
Map::iterator i=params_u.find(键);
返回boost::lexical_cast(boost::get(i->second));
}
//这是过载,而不是专门化
模板
const std::vector&Parameters::get_impl(const std::string&key,std::vector*)
{
//矢量特定代码
}
get
中的static\u cast(0)
只是消除调用歧义的一种巧妙方法
是T*
,将它作为第二个参数传递给get\u impl
将帮助编译器选择get\u impl
的正确版本。如果T
不是std::vector
,将选择第一个版本,否则将选择第二个版本。可能重复:您必须在另一个版本中调用它吗name?重载不就行了吗?@你不能基于返回类型重载的方法。@ChristianRau:当然可以用一些模板魔术。template t ft();template int ft(){return 1;}template float ft(){return 0;}struct f{template operator t(){return ft();};int main(){int il=f();float fl f());cout@Nim:您可以将getter
作为一个类模板,而不是将operator()
作为一个函数模板,并定义两个operator()
,每种情况一个(通用和专用)。这样您就不需要专门化getter
。还有一个优点(语法上):您可以将其称为:getter()(key)
,而不是getter()(key)
…但无论哪种方式,它都有一个缺点:getter
无法访问Parameters
类的成员。因此我认为,最好让实际实现成为类的成员(就像我所做的那样),而不是定义新的结构。非常感谢,这正是我想要的。static_cast(nullptr)链接是死的这对我来说在gcc9上不起作用,它仍然选择非向量impl
template<typename T>
const T& Parameters::get(const std::string& key)
{
//read the explanation at the bottom for the second argument!
return get_impl(key, static_cast<T*>(0) );
}
//general case
template<typename T>
const T& Parameters::get_impl(const std::string& key, T*)
{
Map::iterator i = params_.find(key);
return boost::lexical_cast<T>(boost::get<std::string>(i->second));
}
//this is overload - not specialization
template<typename T>
const std::vector<T>& Parameters::get_impl(const std::string& key, std::vector<T> *)
{
//vector specific code
}