【问题标题】:C++ Template to return different types with same parametersC ++模板返回具有相同参数的不同类型
【发布时间】:2015-08-12 10:06:06
【问题描述】:

基本上,如果我有这个:

template <class T> 
inline T Foo(int x)
{
    switch (x)
    {
        case 0:
            return true;
            break;
        case 1:
            return false;
            break;
        case 2:
            return 100;
            break;
        default:
            break;
    }
}

然后我必须这样使用它:

int x = Foo<int>(2);
bool b = Foo<bool>(0);

如果可能的话,我更希望能够这样做:

int x = Foo(2);
bool b = Foo(0);

我看到了this question,但很难将它应用到我的场景中。任何帮助或指向正确的方向都会很棒。

【问题讨论】:

  • 如所写,只需返回一个int。到bool 的隐式转换将做正确的事情。此外,您可能希望在您的 default 案例中添加一些东西,而不是在函数结束时调用未定义的行为 - 也许会抛出异常。
  • 您传递给Foo 的值在编译时是否已知?例如,您可以使用int x = Foo&lt;2&gt; ();
  • @T.C.这适用于仅使用 int/bool 的情况,但如果我希望有更多返回类型怎么办?
  • 正如所写的那样,那似乎是很糟糕的设计。但也许那是因为您在示例中过于简化了问题。如果您知道编译时将返回的类型,为什么要创建一个方法,其 switch 语句的唯一目的似乎是选择返回该类型的正确“内部方法”?为什么不只是有不同的方法?
  • 打电话给int x = Foo(3); 会发生什么?

标签: c++ templates


【解决方案1】:

这里的想法是使用可转换为我们想要的返回类型的返回类型。 在这种情况下,我们可以使用可以转换为 int、bool、double 等的字符串。使用 stringstream。

inline polyType Foo(int x)
{
    polyType result;
    switch (x)
    {
        case 0:
            result.value = "0";
            break;
        case 1:
            result.value = "1";
            break;
        case 2:
            result.value = "100";
            break;
        case 3:
            result.value = "awesome";
            break;
        case 4:
            result.value = "10.22";
            break;
        default:
            break;
    }
    return result;
}

其中 polyType 将声明为以下类型,并为任何类型名称 T 进行类型转换,如 here 所述

struct polyType {
    string value;

    template <typename T>
    operator T() const
    {
       stringstream ss(value);
       T convertedValue;
       if ( ss >> convertedValue ) return convertedValue;
       else throw runtime_error("conversion failed");
    }
 };

现在你可以把它当作

int a = Foo(2);
bool b = Foo(0);
float c = Foo(4);

在您的情况下,如果您只想使用 int 和 bool。因为 int 可以转换为 bool,所以你可以只返回 int。不要返回“true”和“false”,而是使用 1 和 0。

int Foo(int x)
{
    switch (x)
    {
        case 0:
            return 1;
            break;
        case 1:
            return 0;
            break;
        case 2:
            return 100;
            break;
        default:
            break;
    }
}

【讨论】:

    【解决方案2】:

    AFAIK 编译器不能仅根据返回类型隐式确定模板参数。如果您将它们作为参数(函数模板)传入,它通常可以隐式确定它们。

    因此,可能会更好的一件事是通过引用传递模板参数:

    template <typename T>
    void Foo(int x, T& arg1)
    {
        if (x == 0)
            arg1 = true;
        else if (x == 1)
            arg1 = "test";  
    }
    
    bool a = false;
    std::string b;
    
    Foo(0, a);
    Foo(1, b);
    

    【讨论】:

    • 另外,如果你想要多个参数,你可能会使用可变参数模板(c++11 特性)。
    猜你喜欢
    • 2019-12-18
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    相关资源
    最近更新 更多