引用数组参数很有用,因为它可以防止衰减,从而可以推断出数组的大小。
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/