Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何专门化std::vector<;的模板成员函数;T>;_C++_Templates - Fatal编程技术网

C++ 如何专门化std::vector<;的模板成员函数;T>;

C++ 如何专门化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>(

我需要用两种不同的方式定义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>(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
from
get
,如下所示:

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
}