【问题标题】:Autodetect return type of template function自动检测模板函数的返回类型
【发布时间】:2018-02-15 07:03:13
【问题描述】:

我有一些带有函数的类。在所有类中,函数具有相同的名称和参数类型,但返回类型不同。我需要一个模板函数,它可以自动检测正确的模板替换而无需尖括号。

说明问题的测试代码:

struct Float
{
    static Float convert(int i)
    {
        return Float{static_cast<float>(i)};
    }

    float _f;
};

struct Int
{
    static Int convert(int i)
    {
        return Int{i};
    }

    int _i;
};

template<typename T>
T convert(int i)
{
    return T::convert(i);
}


int main()
{
    Float f1 = convert<Float>(10);
    Int i1 = convert<Int>(10);

    // Float f2 = convert(10); compilation error
    // Int i2 = convert(10); compilation error

    return 0;
}

附:模板让我疯狂我想要但无法理解它们。

【问题讨论】:

  • 模板选择“不带尖括号”需要参数推导。函数的返回类型不是参数。所以你可以放心,你不能从这里到达那里。

标签: c++ c++11 templates c++14


【解决方案1】:

不确定它是否完全符合您的需求,但您可以使用类和模板化转换运算符模拟您想要的:

class convert {
    int arg;
public:
    convert(int arg) : arg(arg) {}

    template<class T>
    operator T() const {
      return T::convert(arg);
    }
};

由于模板参数推导适用于模板化转换运算符,您可以这样写:

Float f1 = convert(10);
Int i1 = convert(10);

如你所愿。

【讨论】:

  • 那太好了。这可能是将函数模板化为其返回类型的唯一方法。这是一个很好的技巧,我会记住的。
  • 不错的把戏。对我来说已经足够好了。只想以这种方式添加 Float f1 = convert&lt;Float&gt;(10) 不会工作。但是可以换成Float f1 = static_cast&lt;Float&gt;(convert(10))
  • @IvanRomanov - 嗯,是的,这就是它的长短。你可以有一个但不能有另一个,因为现在它不再是一个函数了。
【解决方案2】:

为什么需要转换功能?您可以使用单个参数构造函数来完成相同的工作。

struct Float
{
    Float(int i)
    {
        _f =  static_cast<float>(i);
    }

    float _f;
};

struct Int
{
    Int(int i)
    {
        _i = static_cast<int>(i);
    }

    int _i;
};

int main()
{
    Float f2 = 10;
    Int i2   = 10;

    return 0;
}

如果您担心对构造函数的隐式调用,可以将其设为显式

struct Float
{
    explicit Float(int i)
    {
        _f =  static_cast<float>(i);
    }

    float _f;
};

int main()
{
    Float f2 = Float(10);
    return 0;
}

如果具有相同名称和相同类型输入参数的函数可以产生不同的返回类型,则会影响代码的可读性。

【讨论】:

  • 我不能使用构造函数。类必须支持聚合初始化。我也有很多课程,我不想重复功能。全局::convert 函数做一个常见的简单操作。以return T::convert(i * 2); 为例。
猜你喜欢
  • 2015-07-20
  • 1970-01-01
  • 1970-01-01
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-30
  • 1970-01-01
相关资源
最近更新 更多