【问题标题】:Using auto in output parameter在输出参数中使用 auto
【发布时间】:2015-11-19 12:03:09
【问题描述】:

有没有办法在这种情况下使用 auto 关键字:

void foo(bar& output){
    output = bar();
} 

int main(){
   //Imaginary code
   auto a;
   foo(a);
}

当然,不可能知道a是什么类型。因此,解决方案应该是以某种方式将它们合并到一个句子中。这个可以吗?

【问题讨论】:

  • 我不这么认为..如果你给foo添加一个重载会发生什么?
  • 如果你在写程序的时候不知道a的类型,你就有一个不可能的问题。对于函数,解决方案是模板,但您确实需要知道您声明的变量的类型,一种或另一种方式。
  • 简单的答案是否定的(顺便说一句,将它们合并成一个句子是什么意思)。
  • auto 关键字告诉编译器使用初始化器推断 RHS 的数据类型,因此没有初始化器编译器无法推断类型
  • 声明更简单:除非类型可以在它出现的同一语句中派生,否则不能使用 auto。

标签: c++ c++11 auto


【解决方案1】:

您似乎想要默认初始化给定函数期望作为参数类型的对象。

auto 无法做到这一点,但你可以编写一个 trait 来提取函数期望的类型,然后用它来声明你的变量:

namespace detail {
    //expects the argument number and a function type
    template <std::size_t N, typename Func>
    struct arg_n;

    //does all the work
    template <std::size_t N, typename Ret, typename... Args>
    struct arg_n <N, Ret (Args...)> {
        using type = std::remove_reference_t<
                         std::tuple_element_t<N, std::tuple<Args...>>
                     >;   
    };
}

//helper to make usage neater
template <std::size_t N, typename Func>
using arg_n = typename detail::arg_n<N, Func>::type;

然后你像这样使用它:

//type of the first argument expected by foo
arg_n<0,decltype(foo)> a{};
foo(a);

当然,一旦你重载这个函数,这一切都会失败。

【讨论】:

  • 这很棒,虽然我没有理解所有的模式,但结果正是我想要的。但是,我担心在实际程序中使用它,因为有人(几年后)会希望编写此代码的人下地狱:D
  • @HumamHelfawi 实际上,这种代码在通用上下文中是很正常的。如果您认为维护人员会觉得它很迟钝,您可能需要更多的 cmets。
【解决方案2】:
bar foo()
{
    return bar{};
}

int main()
{
    auto a = foo();
}

所有现代编译器都会进行复制省略,根本不会有副本。

【讨论】:

  • 虽然这展示了 auto 的使用,但它避免了这个问题,因为它没有使用 out 参数。
  • @ChrisBetti 在这种情况下,最好不要将引用传递给某个构造实例,然后将新实例分配给它。更好的按值返回并将其分配给新创建的auto 变量。
  • 我 100% 同意你的看法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多