我很困惑为什么你可以定义像
这样的函数int func_useless(int) { return 2; }
将未命名的int作为输入,但不执行任何操作,与
不同int func_useful(int a) { return a; }
例如,您可以致电
int x = func_useless(3); // x is 2
需要将int传递给func_useless
,但不会产生任何结果。
何时传递不能使用的东西会有用?为什么这是该语言的一个特征?
答案 0 :(得分:2)
当你只关心参数的类型而不关心它的值时。
std::nullptr_t
或标记类型,例如std::allocator_arg_t
或std::nothrow_t
或std::piecewise_construct_t
或std::input_iterator_tag
。< / LI>
可能是因为该参数仅用于控制重载决策,例如:
template<class T>
auto do_foo(const T& t, int) -> decltype(t.foo()) { return t.foo(); }
template<class T>
void do_foo(const T& t, long) { /* default implementation */ }
// call t.foo() if valid, otherwise provide a default implementation
template<class T>
decltype(auto) foo(const T& t) { return do_foo(t, 0); }
do_foo
的第二个参数的值无关紧要;它只用于控制do_foo(t, 0)
调用时的do_foo
调用的重载分辨率,通过使第一个更好。
同样,我们有operator++()
(前缀)和operator++(int)
(后缀)及其--
对应物; postfix ++
/ --
运算符的实现很少关注int
参数的值;它存在消除前缀和后缀的歧义。
答案 1 :(得分:2)
一个用途是标签调度,这是模板编程中一种有用的技术:
#include <iostream>
struct ping_type {};
struct pong_type {};
static constexpr ping = ping_type {};
static constexpr pong = pong_type {};
void action(ping_type) {
std::cout << "ping" << std::endl;
}
void action(pong_type) {
std::cout << "pong" << std::endl;
}
int main()
{
action(ping);
action(pong);
}
答案 2 :(得分:1)
这是一个用例。你有一个函数,它接受一个函数,并用它做一些事情:
int sumFrom0To9(int *func(int)) {
int acc = 0;
for (int i = 0; i < 10; i++) { acc += func(i); }
return acc;
}
你可以传入你想要的任何单个arg函数,包括比如这样的东西:
int identity(int) { return 1; }
答案 3 :(得分:0)
我无法想出任何有用的理由。
我期待你得到的是最令人烦恼的解析:
int main()
{
int funk1();
int funk2(int());
funk2(funk1);
}
这是一个声明,你不需要这里的名字。它们可能在定义点命名。
编辑:
其实我确实想到了一个用途:
int whatnot() { return 6; }
void somefun(int (*callback)(int()))
{
callback(whatnot);
}
int my_callback(int()) { return 42; }
int main()
{
somefun(my_callback);
}
my_callback
不需要或不使用函数参数,但需要接受它才能遵守somefun
指定的回调接口。
答案 4 :(得分:0)
如果要保留函数的二进制接口(不更改其签名)但不再对参数有任何用处并希望关闭有关未使用参数的编译器警告,则未命名的参数有时会很有用。