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++ 在没有模板专门化的情况下更改函数的返回类型。C++;_C++_Templates_Return - Fatal编程技术网

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

C++ 在没有模板专门化的情况下更改函数的返回类型。C++;,c++,templates,return,C++,Templates,Return,我想知道是否有可能根据函数被赋值的变量类型来改变函数的返回类型。这里有一个简单的例子来说明我的意思 我想创建一个函数,从字符串解析int、bool或float变量。例如 Int value = parse("37"); Float value = parse("3.14"); Bool value = parse("true"); 我理解如果我将这个函数设置为模板,那么变量类型必须从参数列表中确定,参数列表总是字符串。用C++来做这件事还有别的办法吗? < P>不幸的是,这是不可能的。在C++

我想知道是否有可能根据函数被赋值的变量类型来改变函数的返回类型。这里有一个简单的例子来说明我的意思

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

Int value = parse("37");
Float value = parse("3.14");
Bool value = parse("true");

我理解如果我将这个函数设置为模板,那么变量类型必须从参数列表中确定,参数列表总是字符串。用C++来做这件事还有别的办法吗?

< P>不幸的是,这是不可能的。在C++中,不可能根据其返回值重载函数。您必须有3个函数,ParseInt、ParseFloat和ParseBool,或者使用函数模板。

您可以返回void*,然后根据需要强制转换结果


不过我建议不要这样做。C++是一种强类型语言。这样做的好处是编译器可以比动态类型语言更早地捕获错误

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

template T parse(const string&str){/*do stuff for other type*/}
模板int-parse(conststring&str){/*dostufforints*/}
模板双解析(conststring&str){/*为双精度做一些事情*/}
模板boolparse(conststring&str){/*为bools做一些事情*/}
//等等。
然后作为

int value = parse<int>("37");
double value = parse<double>("3.14");
bool value = parse<bool>("true");
int value=parse(“37”);
双值=解析(“3.14”);
布尔值=解析(“真”);
如果你已经知道这一点,就忽略这个答案,但你的问题并不清楚你是否意识到这是可能的

当然,如果您所做的不是真正的泛型(因此您必须为要分析的每个类型专门化),那么编写模板无论如何都不是正确的做法

顺便说一句,您可以用一个类似这样的函数来完成这项工作(假设您真正想要做的是解析):

#包括
模板T解析(常量字符串和str)
{
T;
标准:istringstream sstr(str);
sstr>>t;
返回t;
}

这将适用于任何默认的可构造的流可提取类型,包括所有内置的INS/< P> < P>不允许这种行为在C++中使用。要允许它,就必须能够在相同的范围内定义相同名称的函数,这些函数只在返回类型上有所不同。这在C++中是不合法的。


C++可以对重写的虚函数执行一些返回类型专门化,例如协变返回类型。但它不支持您正在寻找的内容

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

像这样:

template<class T> void parse(const std::string &input, T& output);
应该有用

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

istringstream is(input);
input >> d;
如果你有一些复杂的格式,我有一个很幸运的技巧,那就是用自定义操作符>>创建自定义对象来提取数据

然后可能是这样的:

istringstring is(input);
input >> LineExtracter(x, y, d);

这可以通过转换函数来完成

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); }
它应该能很好地工作。顺便说一句,您可以直接使用该类。我建议将其重命名为
conversion\u 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"); 
结构转换\u代理{
字符串str;
转换代理(字符串const&str):str(str){}
模板运算符T(){
返回boost::词法转换(str);
}
};
浮动a=转换_代理(“3.1”);

我同意利特比我快一点的说法。使用铸造操作员

#include <iostream>
#include <string>
#include <sstream>

class Convertible
{
public:
    int m_Integer;
    bool m_Bool;
    double m_Double;

    Convertible() : m_Integer(0), m_Bool(false), m_Double(0.0) {};

    operator int() const
    {
        return m_Integer;
    }
    operator bool() const
    {
        return m_Bool;
    }
    operator double() const
    {
        return m_Double;
    }
};

Convertible parse(std::string data)
{
    Convertible l_result;

    std::istringstream converter(data);
    converter >> l_result.m_Integer;

    std::istringstream converter2(data);
    converter2 >> l_result.m_Bool;

    std::istringstream converter3(data);
    converter3 >> l_result.m_Double;

    return l_result;
}

void main()
{
    int l_convertedInt = parse("2");
    bool l_convertedBool = parse("true");
    double l_convertedDouble = parse("3.14");

    std::cout << "Converted '2' to " << l_convertedInt << std::endl;
    std::cout << "Converted 'true' to " << l_convertedBool << std::endl;
    std::cout << "Converted '3.14' to " << l_convertedDouble << std::endl;
}
#包括
#包括
#包括
敞篷车
{
公众:
整数;
布尔姆布尔;
双m_双;
可转换():m_整数(0),m_布尔(false),m_双精度(0.0){};
运算符int()常量
{
返回m_整数;
}
运算符bool()常量
{
返回m_Bool;
}
运算符double()常量
{
返回m_Double;
}
};
可转换解析(std::字符串数据)
{
可转换l_结果;
std::istringstream转换器(数据);
转换器>>l_result.m_Integer;
std::istringstream转换器2(数据);
转换器2>>l_result.m_Bool;
std::istringstream转换器3(数据);
转换器3>>l_result.m_Double;
返回l_结果;
}
void main()
{
int l_convertedInt=parse(“2”);
bool l_convertedBool=parse(“true”);
双l_convertedDouble=parse(“3.14”);
std::cout这里是我对的改编,以适应我的情况,
parse()
的参数不是字符串类型

注意,我发现我必须引入模板专门化,以避免出现类型转换警告(
float
int

(另请参见。)

#包括
结构MyUnion
{
公众:
联合{
布尔布尔值;
int_值;
浮点数;
};
};
模板T解析(const MyUnion&h)
{
T;
if(typeid(T)=typeid(bool)){
t=h.bool_值;
}else if(typeid(T)=typeid(int)){
t=h.int_值;
}else if(typeid(T)=typeid(float)){
//t=h.float_value;//请参见下面的**警告**;改用float专门化
}
返回t;
}
//“float”模板专门化以避免转换警告。
模板浮点分析(const MyUnion&h)
{
返回h.float_值;
}
int main()
{
MyUnion mu1;mu1.bool_值=true;
MyUnion mu2;mu2.int_值=42;
MyUnion mu3;mu3.float_值=3.14159;

std::cout这几乎不比使用“int parse_int(const string&)”、“double parse_double(const string&)”等更好。这就是为什么我展示了可以使用模板来完成的原因,然后注意到,如果事实上不是这样,您就不想使用模板
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); }
float a = parse("3.1");
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"); 
#include <iostream>
#include <string>
#include <sstream>

class Convertible
{
public:
    int m_Integer;
    bool m_Bool;
    double m_Double;

    Convertible() : m_Integer(0), m_Bool(false), m_Double(0.0) {};

    operator int() const
    {
        return m_Integer;
    }
    operator bool() const
    {
        return m_Bool;
    }
    operator double() const
    {
        return m_Double;
    }
};

Convertible parse(std::string data)
{
    Convertible l_result;

    std::istringstream converter(data);
    converter >> l_result.m_Integer;

    std::istringstream converter2(data);
    converter2 >> l_result.m_Bool;

    std::istringstream converter3(data);
    converter3 >> l_result.m_Double;

    return l_result;
}

void main()
{
    int l_convertedInt = parse("2");
    bool l_convertedBool = parse("true");
    double l_convertedDouble = parse("3.14");

    std::cout << "Converted '2' to " << l_convertedInt << std::endl;
    std::cout << "Converted 'true' to " << l_convertedBool << std::endl;
    std::cout << "Converted '3.14' to " << l_convertedDouble << std::endl;
}