在没有模板专门化的情况下更改函数的返回类型.C++

Mor*_*gan 14 c++ templates return

我想知道是否可以根据分配给它的变量类型来更改函数的返回类型.这是我的意思的一个简单例子.

我想创建一个从字符串中解析int,bool或float变量的函数.例如...

Int value = parse("37");
Float value = parse("3.14");
Bool value = parse("true");
Run Code Online (Sandbox Code Playgroud)

我理解如果我将此函数设为模板,则必须从参数列表中确定变量类型,该列表始终是一个字符串.用c ++还有其他方法吗?

Joh*_*itb 31

这可以通过转换功能完成

struct proxy {
    string str;
    proxy(string const &str):str(str) { }
    template<typename T> operator T() { 
        return boost::lexical_cast<T>(str); 
    }
};

proxy parse(string const &str) { return proxy(str); }
Run Code Online (Sandbox Code Playgroud)

现在你只需要做

float a = parse("3.1");
Run Code Online (Sandbox Code Playgroud)

它应该运作良好.顺便说一句,您可以直接使用该类.我建议将其重命名conversion_proxy为指向它只是发生转换的代理但它本身不进行转换的事实

struct conversion_proxy {
    string str;
    conversion_proxy(string const &str):str(str) { }
    template<typename T> operator T() { 
        return boost::lexical_cast<T>(str); 
    }
};

float a = conversion_proxy("3.1"); 
Run Code Online (Sandbox Code Playgroud)


Tyl*_*nry 12

如果您知道这一点,我无法从您的问题中判断出来,但您确实可以使用模板进行此操作.唯一的问题是,您必须在每次调用时指定要转换的类型,而不是依赖于推理(因为正如您所说,参数类型将始终相同).

template<typename T> T parse(const string& str) { /* do stuff for other types */ }
template<> int parse<int>(const string& str) { /* do stuff for ints */ }
template<> double parse<double>(const string& str) { /* do stuff for doubles */ }
template<> bool parse<bool>(const string& str) { /* do stuff for bools */ }
// etc.
Run Code Online (Sandbox Code Playgroud)

然后调用为

int value = parse<int>("37");
double value = parse<double>("3.14");
bool value = parse<bool>("true");
Run Code Online (Sandbox Code Playgroud)

如果您已经知道这个,请忽略这个答案,但从您的问题中不清楚您是否知道这是可能的.

当然,如果您正在做的事情并不是真正的通用(因此您必须专门针对要解析的每种类型),那么编写模板无论如何都不是正确的事情.

顺便说一下,你可以通过这样的单一函数来做到这一点(假设解析是你真正想要做的):

#include <sstream>
template<typename T> T parse(const string& str) 
{
  T t;
  std::istringstream sstr(str);
  sstr >> t;
  return t;
}
Run Code Online (Sandbox Code Playgroud)

这适用于任何默认可构造的,可流提取的类型,其中包括所有内置函数.

  • 这就是为什么我表明它可以用模板完成,然后注意到你不想使用模板,如果它实际上不是通用的,那么就说明它是如何通用的(对于许多类型). (3认同)

Zan*_*ynx 5

您可以将输出参数作为指针或引用传递.

像这样:

template<class T> void parse(const std::string &input, T& output);
Run Code Online (Sandbox Code Playgroud)

然后像这样的代码:

double d; parse(input, d);
int i; parse(input, i);
Run Code Online (Sandbox Code Playgroud)

应该管用.

但是,您的代码看起来非常适合std :: istringstream,它只是:

istringstream is(input);
input >> d;
Run Code Online (Sandbox Code Playgroud)

如果你有一些复杂的格式,我有一个非常好运的技巧涉及使用自定义运算符>>拉出数据创建自定义对象.

那可能是这样的:

istringstring is(input);
input >> LineExtracter(x, y, d);
Run Code Online (Sandbox Code Playgroud)