【问题标题】:C++ decltype deducing current function returned typeC++ decltype 推导当前函数返回类型
【发布时间】:2014-02-20 03:19:02
【问题描述】:

我想自动推断我正在编写的函数的返回类型。

例子:

std::vector<int> test(){
    decltype(this_function) ret;
    ret.push_back(5);
    ret.push_back(9);
    return ret;
}

到目前为止,我取得的最好成绩是

std::vector<int> test(){
    decltype(test()) ret;
    ret.push_back(5);
    ret.push_back(9);
    return ret;
}

哪个有效但是:

  1. 如果我更改函数名称,我必须更改

    decltype(test())

    进入

    decltype(name())

  2. 如果我更改函数参数,我也必须更改

    decltype(test())

    进入

    decltype(test(param1, param2))

有没有更优雅的方式来做同样的事情?

【问题讨论】:

  • FWIW,在 C++14 中,您将能够执行 the opposite
  • 我有时想知道为什么人们会如此努力地不从前一行复制几个字符......你认为这会更具可读性吗?您是否假设可以在不查看定义的情况下更改声明中的返回类型?
  • @jrok:我不会做太多宣传,人们可能想要使用它! [而且我不是特别喜欢这个主意 :)]
  • @jrok 我已经看到了,但我更喜欢这种方法。如果有一种干净的方法可以做到这一点。这样你仍然可以在标题中返回类型。 ..这对于可读性非常重要恕我直言..
  • @DavidRodríguez-dribeas 我会说概念(如果它们进入 C++ 17)是未来标准头文件中的限制因素,而 autodecltype 与 @987654330 相比更方便@ 在模板中定义类型。

标签: c++ c++11 types decltype type-deduction


【解决方案1】:

命名返回类型?

template <typename T=std::vector<int>>
T test(){
    T ret;
    ret.push_back(5);
    ret.push_back(9);
    return ret;
}

请不要让我用enable_if 来限制它。

【讨论】:

  • 这显然不一样。它定义了一系列函数,虽然您可以使用 enable_if 来约束它(正如您所提到的),但它与单个函数不同。例如,您不能使用它来声明/定义虚函数。
  • @DavidRodríguez-dribeas 但虚函数可以调用这个“实现”函数。
【解决方案2】:

这个问题很矛盾:

在这个例子中

std::vector<int> test(){
    decltype(test()) ret;
    ret.push_back(5);
    ret.push_back(9);
    return ret;
}

该函数必须假设 decltype 是一个支持 push_back 且值类型为 int 的容器。没有办法预测它。只需更改返回类型(为双精度)就会破坏它。

【讨论】:

    【解决方案3】:

    怎么样:

    typedef std::vector<int> my_return_type;
    
    my_return_type test(){
        my_return_type ret;
        ret.push_back(5);
        ret.push_back(9);
        return ret;
    }
    

    我认为没有宏你不会有更好的东西:)

    【讨论】:

    • @n.m.使用模板,您可以使用不必要的类型授权多个版本的函数,或者明确禁止它们添加一些丑陋的代码:)
    • @drax Pfft - 称之为功能!调用者可指定的返回类型。我真的很想念我的营销号召。
    • @Casey 我无法战胜这个:D
    • @drax 对不起,我不明白。你是说 any 函数模板有问题吗?哦,标准库的一半,它现在没用了吗,因为“您要么授权具有不必要的类型的函数的多个版本,要么明确禁止它们添加一些丑陋的代码”?标准委员会听到这个消息会感到惊讶。
    • @n.m.这难道不是“概念”背后的全部原因吗? :) IMO 在 STL 中这在很大程度上是值得的,在 OP 的情况下,唯一的原因是避免复制一种类型名称,是否值得将您的简单功能提升为更强大的模板版本并可能改变方式你的用户使用你的代码?
    【解决方案4】:

    这可能看起来很奇怪,但我认为它可以满足您的需求。

    std::vector<int> create() { 
      std::vector<int> x;
      return x; 
    }
    
    auto myfunc() -> decltype(create()) {
      auto X = create();
      return X;
    }
    

    【讨论】:

      【解决方案5】:

      Pre-C++1y(也包括 C++1y 后),您可以使用 lambda 为您进行返回类型推导,如下所示:

      namespace
      {
          auto test = []
          {
              std::vector<int> ret;
              ret.push_back(5);
              ret.push_back(9);
              return ret;
          };
      }
      

      【讨论】:

      • lambda 的问题在于它们不能很好地与 ADL 配合使用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多