我尝试了以下
template<class T>
T fromString(const String& str)
{
return toInt<T>(str.begin());
}
template<>
inline
const String& fromString<const String&>(const String& str)
{return str;}
template<>
inline
double fromString<double>(const String& str)
{return toDouble(str.begin());}
template<>
inline
const char_t* fromString<const char_t*>(const String& str)
{return str.begin();}
然而,似乎编译器试图调用第一个版本,它只适用于整数并具有显式实例化:
In function `Herbs::Stringbase<char16_t> Herbs::fromString<Herbs::Stringbase<char16_t> >(Herbs::Stringbase<char16_t> const&)':
...: undefined reference to `Herbs::Stringbase<char16_t> Herbs::toInt<Herbs::Stringbase<char16_t> >(char16_t const*)'
该函数就像这样调用
template<class T>
T itemFirstGet() const
{return fromString<T>(m_items[0]);}
m_items是类中的字符串数组。
答案 0 :(得分:1)
您可以将函数重载/特化委托给结构,并使一般情况不实现:
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <type_traits>
namespace Detail {
template<typename T, typename Enable = void> struct FromString;
// Note: This could consume floating point types and more.
template<typename T>
struct FromString<T, typename std::enable_if<std::is_integral<T>::value>::type>
{
typedef T return_type;
static return_type apply(const std::string& str) {
std::istringstream s(str);
return_type result;
s >> result >> std::ws;
if( ! s.eof())
throw std::runtime_error("Invalid Integral Conversion");
return result;
}
};
template<>
struct FromString<std::string>
{
typedef const std::string& return_type;
static return_type apply(const std::string& str) {
return str;
}
};
}
template<typename T>
inline typename Detail::FromString<T>::return_type
from_string(const std::string& str) {
return Detail::FromString<T>::apply(str);
}
struct Unknown;
int main() {
std::cout << from_string<int>("1") << ' ' << from_string<std::string>("Hello") << '\n';
// error: no matching function for call to ‘from_string(const char [1])’
// note: candidate is:
// note: template<class T> typename Detail::FromString<T>::return_type from_string(const string&)
// note: template argument deduction/substitution failed:
// In substitution of ‘template<class T> typename Detail::FromString<T>::return_type from_string(const string&) [with T = Unknown]’:
// required from here
// error: invalid use of incomplete type ‘struct Detail::FromString<Unknown, void>’
// error: declaration of ‘struct Detail::FromString<Unknown, void>’
// from_string<Unknown>("");
// Exception
from_string<int>("1 + 1");
}