引用数组参数很有用,因为它可以防止衰减,从而可以推断出数组的大小。

template <typename T, std::size_t N>
constexpr std::size_t array_size(T (&) [N]) noexcept
{
  return N;
}

但是什么时候有用?
template<typename T>
void foo(T& t)
{
  // we now have a reference to bar
}

void bar() { }

int main()
{
    foo(bar);
}

我们何时关心防止指针衰减的功能?我问的是什么时候有用,而不是为什么不禁止这样做。

最佳答案

与对象一样,如果“无对象”(“无功能”)是一个有意义的值,我们将使用一个指针;如果我们希望确保(除非有人坚持用脚射击自己),我们将始终使用一个有效对象(功能)所指。

考虑以下可怜人的函数包装器(有钱人去over there)。

template<typename>
class Function;  // never defined

template<typename ReturnT, typename... ArgT>
class Function<ReturnT(ArgT...)>
{

private:

  ReturnT (*func_)(ArgT...);

public:

  // Will also accept a 'nullptr'
  Function(ReturnT (*func)(ArgT...)) noexcept : func_ {func}
  {
  }

  ReturnT
  operator()(ArgT... args)
  {
    return this->func_(args...);
  }
};

现在,我们可以编写以下程序,该程序运行正常。
#include <iostream>

int
add(int a, int b)
{
  return a + b;
}

int
main()
{
  Function<int(int, int)> f {add};    // ok
  std::cout << f(5, 7) << std::endl;  // ok, prints 12
}

但是,我们也可以编写以下程序,但效果不佳。
int
main()
{
  Function<int(int, int)> f {nullptr};  // compiles fine
  std::cout << f(5, 7) << std::endl;    // compiles fine, crashes at run-time
}

相反,如果我们在模板的定义中将(*func)替换为(&func)
// Won't accept a 'nullptr'
Function(ReturnT (&func)(ArgT...)) noexcept : func_ {func}
{
}

线
Function<int(int, int)> f {nullptr};  // compile-time error

会触发编译时错误。

关于c++ - 什么时候引用功能有用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28709758/

10-11 21:13