如何在编译时检查函数是否具有默认参数值?
How to check in compile time that the function has default parameter value?
所有尝试做的就是制作这段代码
int main() {
if constexpr( ??? ) {
std::cout << "Yes\n";
std::cout << f() << '\n';
std::cout << f(42) << '\n';
}
else {
std::cout << "No\n";
}
return 0;
}
- 如果函数
f
定义为这些示例中的任何一个,则编译
// Example 1
int f(int n = 0) { return n; }
// Example 2
int f(int n) { return n; }
int f() { return 0; }
// Example 3
int f(int n) { return n; }
- 并显示
Yes
例如 1
和 2
,并显示 No
例如 3
。
这可能吗?我想我见过有人用 SFINAE 这样做,但我不记得它是如何完成的以及我在哪里看到的。提前谢谢你。
if constexpr
无法保护格式错误的代码 在任何模板 之外( 例如 ,在 main
).显而易见的事情是编写一个接受 f
本身作为模板参数的模板,但要做到这一点,您必须 reify 您的重载集。通常的做法是作为 SFINAE 友好的 函数对象:
template<class F,class=void>
constexpr bool opt=false;
template<class F>
constexpr bool opt<F,decltype(std::declval<F>()(1),void(std::declval<F>()()))> =true;
template<class F> int use(F &&x) {
if constexpr(opt<F>) return x(1)+x();
else return 0;
}
const auto f_=[](auto &&...aa) -> decltype(f(std::forward<decltype(aa)>(aa)...))
{return f(std::forward<decltype(aa)>(aa)...);};
int main() {use(f_);}
在某些情况下,还可以选择创建一个“假”模板,该模板使用 正式 依赖但始终使用您想要的类型的调用,但这对于如果您的 f
需要参数,则立即调用不带参数的 f()
格式错误(可能不需要诊断),因为它不能依赖于模板参数。
所有尝试做的就是制作这段代码
int main() {
if constexpr( ??? ) {
std::cout << "Yes\n";
std::cout << f() << '\n';
std::cout << f(42) << '\n';
}
else {
std::cout << "No\n";
}
return 0;
}
- 如果函数
f
定义为这些示例中的任何一个,则编译
// Example 1
int f(int n = 0) { return n; }
// Example 2
int f(int n) { return n; }
int f() { return 0; }
// Example 3
int f(int n) { return n; }
- 并显示
Yes
例如1
和2
,并显示No
例如3
。
这可能吗?我想我见过有人用 SFINAE 这样做,但我不记得它是如何完成的以及我在哪里看到的。提前谢谢你。
if constexpr
无法保护格式错误的代码 在任何模板 之外( 例如 ,在 main
).显而易见的事情是编写一个接受 f
本身作为模板参数的模板,但要做到这一点,您必须 reify 您的重载集。通常的做法是作为 SFINAE 友好的 函数对象:
template<class F,class=void>
constexpr bool opt=false;
template<class F>
constexpr bool opt<F,decltype(std::declval<F>()(1),void(std::declval<F>()()))> =true;
template<class F> int use(F &&x) {
if constexpr(opt<F>) return x(1)+x();
else return 0;
}
const auto f_=[](auto &&...aa) -> decltype(f(std::forward<decltype(aa)>(aa)...))
{return f(std::forward<decltype(aa)>(aa)...);};
int main() {use(f_);}
在某些情况下,还可以选择创建一个“假”模板,该模板使用 正式 依赖但始终使用您想要的类型的调用,但这对于如果您的 f
需要参数,则立即调用不带参数的 f()
格式错误(可能不需要诊断),因为它不能依赖于模板参数。