是否可以在编译时检测函数的默认参数?

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

Live Demo