C++ 如何从std::string转换为模板化的T,或者如果可能的话,可以先检查一下?

C++ 如何从std::string转换为模板化的T,或者如果可能的话,可以先检查一下?,c++,c++11,C++,C++11,如何从std::string转换为模板化的T,或者如果可能的话,可以先检查一下 我在类型T上有模板函数。有输入std::string, 我需要把这个字符串转换成T,例如,如果这个字符串是42, 然后: 其他专门知识留给读者作为练习。您可以编写一个通用模板来涵盖3和4: template <typename T> T to(std::string const & s) { return T(s); } template<typename T,typename=v

如何从std::string转换为模板化的T,或者如果可能的话,可以先检查一下

我在类型T上有模板函数。有输入std::string, 我需要把这个字符串转换成T,例如,如果这个字符串是42, 然后:


其他专门知识留给读者作为练习。

您可以编写一个通用模板来涵盖3和4:

template <typename T>
T to(std::string const & s) {
    return T(s);
}
template<typename T,typename=void>
struct convert_string_to : std::false_type {};
template<typename T>
struct convert_string_to<
  T,
  typename std::enable_if<std::is_convertible<std::string const&, T>::value>::type
> : std::true_type {
  T operator()( std::string const& src ) const { return src; }
};
template<typename I>
struct convert_string_to<
  I,
  typename std::enable_if<std::is_integral<I>::value>::type
> : std::true_type {
  I operator()( std::string const& src ) const {
    // TODO: insert code to convert `src` to an integer
  };
};
template<typename I>
struct convert_string_to<
  F,
  typename std::enable_if<std::is_floating_point<F>::value>::type
> : std::true_type {
  F operator()( std::string const& src ) const {
    // TODO: insert code to convert `src` to a floating point
  };
};
template<typename T>
typename std::enable_if< convert_string_to<T>::value, T >::type
convert_string( std::string const& str ) {
  return convert_string_to<T>()(str);
}
然后专门针对需要特殊转换的类型:

template <>
float to<float>(std::string const & s) {
    return std::stof(s);
}
应该可以使用SFINAE允许通过stringstream转换为所有数字类型;但这超出了我的模板争论的舒适区,留给读者作为练习

template<typename T,typename=void>
struct convert_string_to : std::false_type {};
template<typename T>
struct convert_string_to<
  T,
  typename std::enable_if<std::is_convertible<std::string const&, T>::value>::type
> : std::true_type {
  T operator()( std::string const& src ) const { return src; }
};
template<typename I>
struct convert_string_to<
  I,
  typename std::enable_if<std::is_integral<I>::value>::type
> : std::true_type {
  I operator()( std::string const& src ) const {
    // TODO: insert code to convert `src` to an integer
  };
};
template<typename I>
struct convert_string_to<
  F,
  typename std::enable_if<std::is_floating_point<F>::value>::type
> : std::true_type {
  F operator()( std::string const& src ) const {
    // TODO: insert code to convert `src` to a floating point
  };
};
template<typename T>
typename std::enable_if< convert_string_to<T>::value, T >::type
convert_string( std::string const& str ) {
  return convert_string_to<T>()(str);
}

我会考虑返回一个STD::可选或STD::预期的等价物都是为将来的标准提出的,但是它们的设计完全支持C++ 11而不是T,允许错误发生而不使用异常。 此外,还需要移动构造版本


在这种情况下,如果类型不起作用,则convert_字符串上的重载解析将失败,并且它适用于所有整数类型和所有浮点类型,而不仅仅是int和float或某些固定集。

这已经存在;它叫


我看不出如何根据返回类型进行专门化或模板推导,因此需要将左值传递给convert函数

此外,虽然可能需要使用专门化,但转换“任意类型”似乎需要模板

类似这样的工作原理:

template <typename T>
void convert(T& lhs, const std::string& s) { lhs= T(s); }

template<>
void convert<int>(int& lhs, const std::string& s) { lhs= std::stoi(s); }

 ... (all other conversions)


@remyabel不知道你的意思。。。我需要首先检查我是否可以从字符串转换为T,如果可以,那么就这样做。仅此而已。boost::词法转换mind@user是的,我倒过来了,忽略我的评论。@arne:是的,虽然词法转换使用运算符,但它不会使用转换构造函数,使用std::string。我很难理解为什么您认为需要函数作为函数模板。你能解释一下吗?无效或退货都是错误的。它们并不是真的在一起。这和@IgorTandetnik建议的不一样吗?@user311311311311:事实上,我们都写了非常相似的答案。应该尽可能避免函数模板的专门化,使用重载>@DavidRodríguez dribeas请告诉我如何仅在返回类型上重载。这似乎是一个很好的解决方案@igortandetnik字符串的专门化是多余的,因为它与通用版本的功能相同。您也许可以返回conststring&以允许在某些情况下避免复制;模板T convert_helper const string&s,unused&&是您的助手。模板T convert const string&s{return convert_helper s,unused;}然后对convert_helper执行调度。添加到未使用的转换功能以获得更多的魔力。这并不是那么简单,所以我想知道,如果您不提供示例,为什么还要发布这些内容。@user311311311:好了。有一条但书:这与OP指定的内容不完全相符。它需要类型的运算符>>,而不仅仅是采用字符串的类型的构造函数。诚然,拥有运营商>>通常是更好的选择,但仍然有一个区别值得注意。@Jerry:是的,公平地说,这是一个有点懒的帖子,但我对sweet repz很着迷。实际上,我实现了我自己的词法转换,通过一系列专门化,它使用各种直接转换函数来转换整数类型,在基本情况下使用boost::词法转换。@user311311311:这确实使用了模板。但是,是的,正如我所说,这也是我在真实代码中所做的。然而,这是一个更简单的解决方案,如果您不需要它,则不需要重新发明。专业化或模板推导是如何基于返回发生的type@GlennTeitelbaum您可以将其用作转换字符串。或者,您可以稍后执行struct do_convert{std::string const&s;模板运算符Tconst{return convert_strings;};如果您不喜欢指定类型,请使用do_convert_later convert std::string const&s{return{s};}。+1:我们不知道这是他试图做的,但如果他是,那么这就是方法。您对词法转换有什么看法?这比上面Igor的解决方案更好吗?
#include <iostream>
#include <boost/lexical_cast.hpp>

int main()
{
   const std::string s1 = "abc",
                     s2 = "123",
                     s3 = "45.6";

   const int   i = boost::lexical_cast<int>(s2);
   std::cout << i << ' ';

   const float f = boost::lexical_cast<float>(s3);
   std::cout << f << ' ';

   try {
      boost::lexical_cast<int>(s1);  // can't do this!
   }
   catch (boost::bad_lexical_cast&) {
      std::cout << '!' << '\n';
   }
}

// Output: 123 45.6 !
template <typename T>
void convert(T& lhs, const std::string& s) { lhs= T(s); }

template<>
void convert<int>(int& lhs, const std::string& s) { lhs= std::stoi(s); }

 ... (all other conversions)
int x;
convert(x,"31");