代码之家  ›  专栏  ›  技术社区  ›  Peter Ruderman

如何编写返回引用或值的函数模板?

  •  11
  • Peter Ruderman  · 技术社区  · 6 年前

    我想编写一个函数模板,根据编译时表达式返回引用或值。到目前为止我试过的是这样的:

    template<typename T>
    auto&& Func()
    {
      if constexpr (some_compile_time_expression)
      {
        return GetReferenceFromSomewhere();
      }
      else
      {
        return GetValueFromSomewhere();
      }
    }
    

    这对所有类型的引用都适用,但对值不适用。例如,如果 GetValueFromSomewhere 返回A Foo ,然后编译器推断 Func 作为 Foo&& 并警告说我正在返回一个临时的地址。

    有什么办法可以让它工作吗?或者我是不是被迫将这两个分支以某种方式分开(通过函数重载或类似的方式)?

    2 回复  |  直到 6 年前
        1
  •  16
  •   Praetorian    6 年前

    使用 decltype(auto) 对于返回类型占位符,它将保留在 return 陈述

    template<typename T>
    decltype(auto) Func()
    {
      if constexpr (some_compile_time_expression_dependent_on_T)
      {
        return GetReferenceFromSomewhere();
      }
      else
      {
        return GetValueFromSomewhere();
      }
    }
    

    Live demo

        2
  •  3
  •   Daniel Langr    6 年前

    pretorian的答案很完美,但是你可能还想了解 std::conditional ,使用范围更广。例如,考虑 data_ 类型的成员变量 int 以及一个成员函数,它返回 达塔 按引用或按值(取决于某些编译时条件):

    template <bool COND>
    std::conditional_t<COND, int&, int> data() { return data_; }
    

    这是不可能的 decltype(auto) . 也可以使用相同的技术通过引用/值将参数传递给函数:

    template <bool COND>
    void f(std::conditional_t<COND, int&, int> param);
    

    或者,可以在复制/移动构造函数之间切换:

    class X {
        X(std::conditional_t<some_cond, const X&, X&&>) = default;
        X(std::conditional_t<some_cond, X&&, const X&>) = delete;
        ...
    };
    

    等。。。