有条件地返回不同类型的C ++函数

时间:2015-10-22 13:22:08

标签: c++ function templates

我正在尝试编写一个模板函数,它将根据传入的字符串返回不同的类型。

OnClientClick

当我运行时,我收到以下错误:

  

错误:没有匹配函数来调用'test(const char [4])

我该如何实现这样的事情?

我的最终目标是编写一个函数,它将返回不同类的对象,具体取决于传递给它的字符串。我知道这可能不是正确的方法。做这样的事的正确方法是什么?

7 个答案:

答案 0 :(得分:4)

你不能这样做,至少不那样做。

为了能够返回不同的类型,你必须先通过引用返回,然后可能返回的类型必须从声明的返回类型继承。

例如:

class Base {
};

class Derived1 : public Base {
};

class Derived2 : public Base {
};

Base& func(string type) {
     static Derived1 d1;
     static Derived2 d2;

     if( type == "Derived1" )
         return d1;
     if( type == "Derived2" )
         return d2;

     //etc
}

答案 1 :(得分:4)

函数始终返回相同类型的值。

您可以做的是返回指向公共基类的指针:

struct A {};

struct B : A {};

struct C : A {};

A* make(const std::string& s)
{
    if (s == "B")
        return new B;
    else if (s == "C")
        return new C;
    else
        return nullptr;
}

答案 2 :(得分:0)

int integer = test<int>("int");
作品。

你不需要通过&#34; int&#34;如果是<>类型的字符串 可以通过函数中的代码检测到int或float。

PS:&#34; floateger&#34;?

答案 3 :(得分:0)

据我所知,在字符串解析时不可能实现返回不同类型的功能。 (我假设字符串是用户输入的结果)。 C ++是强类型语言类型,因此编译器必须知道确切的返回类型。如果字符串值是硬编码的,您可以将实现更改为:

template<typename...> struct rebinder;

template<template<typename...> class Container, typename ... Args>
struct rebinder<Container<Args...>>{
    template<typename ... UArgs>
    using rebind = Container<UArgs...>;
};

或者,如果您不仅限于POD类型,请查看@molbdnilo或@skyking答案。

答案 4 :(得分:0)

我会做这样的事情。不是返回值,而是将其作为第二个参数:

template<class T>
void test(const char *var_type, T& ret) {
    int integer = 42;
    float f = 42.42;

    if (0 == strcmp(var_type, "int")) {
        ret = integer;
    } else if (0 == strcmp(var_type, "float")) {
        ret = f;
    }
}

然后你可以这样称呼它:

int integer = 0;
float f = 0.0;
test((const char *) "int", integer);
printf("%d\n", integer);
test((const char *) "float", f);
printf("%f\n", f);

答案 5 :(得分:0)

使用Boost,您可以使用boost :: variant:

来解决这个问题
typedef boost::variant< int, float, YourSpecialDataType > MixedData;

然后让方法返回此类型:

MixedData test(std::string type) {
   int   integer   = 42;
   float floateger = 42.42;

   if (type == "int")
      return integer;
   if (type == "float")
      return floateger;
}

答案 6 :(得分:0)

通常不可能重载返回的值,因为编译器无法解决它。想象一下如下声明:

your_overloaded_function();

您不会将返回的值存储在任何变量中,因为您对它不感兴趣,那么编译器如何理解您要调用的函数?它不能,简单。

您可以返回层次结构的基类,这确实不是重载的返回值,但它允许您返回不同类的不同实例,从而获得您想要实现的内容。

无论如何,有一些技巧可以明确地得到它。它遵循可能使用部分特化的方法:

#include <iostream>
#include <type_traits>

using namespace std;

template<typename T, typename Enable = void>
struct S { };

template<typename T>
struct S<T, typename std::enable_if<std::is_integral<T>::value>::type>
{
    T operator()() { return 42; }
};

template<typename T>
struct S<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
{
    T operator()() { return 42.42; }
};

int main()
{
    S<int> si;
    S<float> sf;
    int integer = si();
    float float_ = sf();
    cout << "INTEGER: " << integer << endl;
    cout << "FLOAT: " << float_ << endl;
}

也就是说,这是一个涉及整数 float 的片段,如你的例子所示。

无论如何,为了做到我认为你想做的事情,你可以依靠着名的模式,如abstract factory创作模式的家族,而不是依赖在模板上。