是否可以在编译时检测函数的默认参数?
Is it possible to detect the default parameters of a function at compile-time?
#include <thread>
#include <functional>
using namespace std;
void f(int n = 7)
{}
void g(function<void()> fn)
{
fn(); // same as f(7)
}
template<typename Callable>
auto GetDefaultArg(Callable fn, size_t arg_ordinal)
{
// What to put here?
}
int main()
{
auto fn = bind(f, GetDefaultArg(f, 1));
g(fn);
}
如上面的代码所示,我想实现一个模板函数GetDefaultArg
来检测函数的默认参数。
在当前的 C++ 中是否可行?
不,你不能在编译时检测默认参数。
您已经在函数定义中声明了默认参数。但是默认参数并没有链接到函数本身,而是在调用函数的范围内已知的函数声明。
另外说明:您可以为同一功能设置不同的默认参数集。
为了补充 ,我将举例说明他的意思。
我们可以稍后使用额外的默认值重新声明一个函数!
这是什么意思?
让我们从函数声明开始:
// initial declaration; nothing defaulted
void foo(int a, char b, bool c, double d);
我有一些函数 foo
没有默认参数。
我写了一个调用 foo
:
的函数
void CallFoo1()
{
// no default params
foo(1, 'b', true, 2.0);
}
它必须为 foo
中的每个参数提供一个参数。
但是,现在我可以重新声明 foo
(只要我还没有定义它),并给最后一个参数一个默认值:
// add default for last argument
void foo(int a, char b, bool c, double d= 2.0);
然后我编写 另一个 调用 foo
的函数。除了这次我可以将最后一个参数留空:
void CallFoo2()
{
foo(1, 'b', true);
}
我可以继续这样做,每次都使用新的默认值重新声明:
// add default for third argument
void foo(int a, char b, bool c=true, double d);
void CallFoo3()
{
foo(1, 'b');
}
// add default for second argument
void foo(int a, char b='b', bool c, double d);
void CallFoo4()
{
foo(1);
}
// add default for first argument
void foo(int a=1, char b, bool c, double d);
void CallFoo5()
{
// everything is defaulted!
foo();
}
在 foo
的最后一次重新声明之后,foo
的声明由默认值的并集组成(注意:我不能重新默认一个值)。
然后我终于可以提供 foo
的定义了:
void foo(int a, char b, bool c, double d)
{
std::cout << "a = " << a << " b = " << b << " c = " << std::boolalpha << c << " d = " << d << std::endl;
}
让我们来测试一下:
int main()
{
CallFoo1();
CallFoo2();
CallFoo3();
CallFoo4();
CallFoo5();
}
输出:
a = 1 b = b c = true d = 2
a = 1 b = b c = true d = 2
a = 1 b = b c = true d = 2
a = 1 b = b c = true d = 2
a = 1 b = b c = true d = 2
#include <thread>
#include <functional>
using namespace std;
void f(int n = 7)
{}
void g(function<void()> fn)
{
fn(); // same as f(7)
}
template<typename Callable>
auto GetDefaultArg(Callable fn, size_t arg_ordinal)
{
// What to put here?
}
int main()
{
auto fn = bind(f, GetDefaultArg(f, 1));
g(fn);
}
如上面的代码所示,我想实现一个模板函数GetDefaultArg
来检测函数的默认参数。
在当前的 C++ 中是否可行?
不,你不能在编译时检测默认参数。
您已经在函数定义中声明了默认参数。但是默认参数并没有链接到函数本身,而是在调用函数的范围内已知的函数声明。
另外说明:您可以为同一功能设置不同的默认参数集。
为了补充
我们可以稍后使用额外的默认值重新声明一个函数!
这是什么意思?
让我们从函数声明开始:
// initial declaration; nothing defaulted
void foo(int a, char b, bool c, double d);
我有一些函数 foo
没有默认参数。
我写了一个调用 foo
:
void CallFoo1()
{
// no default params
foo(1, 'b', true, 2.0);
}
它必须为 foo
中的每个参数提供一个参数。
但是,现在我可以重新声明 foo
(只要我还没有定义它),并给最后一个参数一个默认值:
// add default for last argument
void foo(int a, char b, bool c, double d= 2.0);
然后我编写 另一个 调用 foo
的函数。除了这次我可以将最后一个参数留空:
void CallFoo2()
{
foo(1, 'b', true);
}
我可以继续这样做,每次都使用新的默认值重新声明:
// add default for third argument
void foo(int a, char b, bool c=true, double d);
void CallFoo3()
{
foo(1, 'b');
}
// add default for second argument
void foo(int a, char b='b', bool c, double d);
void CallFoo4()
{
foo(1);
}
// add default for first argument
void foo(int a=1, char b, bool c, double d);
void CallFoo5()
{
// everything is defaulted!
foo();
}
在 foo
的最后一次重新声明之后,foo
的声明由默认值的并集组成(注意:我不能重新默认一个值)。
然后我终于可以提供 foo
的定义了:
void foo(int a, char b, bool c, double d)
{
std::cout << "a = " << a << " b = " << b << " c = " << std::boolalpha << c << " d = " << d << std::endl;
}
让我们来测试一下:
int main()
{
CallFoo1();
CallFoo2();
CallFoo3();
CallFoo4();
CallFoo5();
}
输出:
a = 1 b = b c = true d = 2
a = 1 b = b c = true d = 2
a = 1 b = b c = true d = 2
a = 1 b = b c = true d = 2
a = 1 b = b c = true d = 2