无法调用具有默认参数的函数特化,因为参数太少
Function specialization with default arguments can't be called because too few arguments
我有this代码
#include <iostream>
#include <type_traits>
enum class Color: char { Red = 'r', Yellow = 'y', Green = 'g' };
template<Color color>
auto say_my_name(unsigned times = 1) {
for (unsigned i = 0; i < times; i++) {
std::cout << static_cast<std::underlying_type_t<Color>>(color) << ' ';
}
std::cout << std::endl;
}
constexpr auto say_red = say_my_name<Color::Red>;
int main()
{
say_my_name<Color::Yellow>(3);
say_my_name<Color::Yellow>();
say_red(2);
say_red(); // too few arguments to function
}
我希望函数 say_red
是 say_my_name
的特化,这样我就可以轻松地在我的代码中调用它,而无需始终提供模板参数。
say_red(2)
工作正常,但 say_red()
无法编译并显示错误消息 “错误:函数参数太少”
有没有办法让我的代码在不指定参数的情况下编译?
作为旁注:如果这样可以解决问题,我也可以将模板参数转换为函数参数。我的问题是,std::bind
在 C++17 中不是 constexpr
,所以这不适合我。
此外,我不想在 say_*
的每个声明中指定默认参数。你可以想象,这是一个例子,我的“现实生活”枚举有 8 个变体,所以我想写尽可能少的代码。
在调用站点替换默认参数。它们不是函数类型的一部分。因此,您需要“某物”来启用 say_red
的默认参数。您可以使用 lambda:
#include <iostream>
#include <type_traits>
enum class Color: char { Red = 'r', Yellow = 'y', Green = 'g' };
template<Color color>
auto say_my_name(unsigned times = 1) {
for (unsigned i = 0; i < times; i++) {
std::cout << static_cast<std::underlying_type_t<Color>>(color) << ' ';
}
std::cout << std::endl;
}
constexpr auto say_red = [](unsigned times = 1){
say_my_name<Color::Red>(times);
};
int main()
{
say_my_name<Color::Yellow>(3);
say_my_name<Color::Yellow>();
say_red(2);
say_red(); // too few arguments to function
}
如果您不介意在每次调用时添加 ()
,您可以使用仿函数:
#include <iostream>
#include <type_traits>
enum class Color: char { Red = 'r', Yellow = 'y', Green = 'g' };
template<Color color>
struct say_my_name {
void operator()(unsigned times = 1) const {
for (unsigned i = 0; i < times; i++) {
std::cout << static_cast<std::underlying_type_t<Color>>(color) << ' ';
}
std::cout << std::endl;
}
};
using say_red = say_my_name<Color::Red>;
int main()
{
say_my_name<Color::Yellow>()(3);
say_my_name<Color::Yellow>()();
say_red()(2);
say_red()(); // too few arguments to function
}
如果您不喜欢额外的 ()
,您可以这样做:
using say_red = say_my_name<Color::Red>;
constexpr auto red_say = say_red{};
int main()
{
red_say(2);
red_say(); // too few arguments to function
}
请注意,您也可以使用构造函数代替 operator()
,但使用 operator()
更灵活,因为它允许您 return 一个值。关键只是分两步进行特化和重载解析(特化仿函数,然后使用一个或零个参数调用 operator()
)。
我有this代码
#include <iostream>
#include <type_traits>
enum class Color: char { Red = 'r', Yellow = 'y', Green = 'g' };
template<Color color>
auto say_my_name(unsigned times = 1) {
for (unsigned i = 0; i < times; i++) {
std::cout << static_cast<std::underlying_type_t<Color>>(color) << ' ';
}
std::cout << std::endl;
}
constexpr auto say_red = say_my_name<Color::Red>;
int main()
{
say_my_name<Color::Yellow>(3);
say_my_name<Color::Yellow>();
say_red(2);
say_red(); // too few arguments to function
}
我希望函数 say_red
是 say_my_name
的特化,这样我就可以轻松地在我的代码中调用它,而无需始终提供模板参数。
say_red(2)
工作正常,但 say_red()
无法编译并显示错误消息 “错误:函数参数太少”
有没有办法让我的代码在不指定参数的情况下编译?
作为旁注:如果这样可以解决问题,我也可以将模板参数转换为函数参数。我的问题是,std::bind
在 C++17 中不是 constexpr
,所以这不适合我。
此外,我不想在 say_*
的每个声明中指定默认参数。你可以想象,这是一个例子,我的“现实生活”枚举有 8 个变体,所以我想写尽可能少的代码。
在调用站点替换默认参数。它们不是函数类型的一部分。因此,您需要“某物”来启用 say_red
的默认参数。您可以使用 lambda:
#include <iostream>
#include <type_traits>
enum class Color: char { Red = 'r', Yellow = 'y', Green = 'g' };
template<Color color>
auto say_my_name(unsigned times = 1) {
for (unsigned i = 0; i < times; i++) {
std::cout << static_cast<std::underlying_type_t<Color>>(color) << ' ';
}
std::cout << std::endl;
}
constexpr auto say_red = [](unsigned times = 1){
say_my_name<Color::Red>(times);
};
int main()
{
say_my_name<Color::Yellow>(3);
say_my_name<Color::Yellow>();
say_red(2);
say_red(); // too few arguments to function
}
如果您不介意在每次调用时添加 ()
,您可以使用仿函数:
#include <iostream>
#include <type_traits>
enum class Color: char { Red = 'r', Yellow = 'y', Green = 'g' };
template<Color color>
struct say_my_name {
void operator()(unsigned times = 1) const {
for (unsigned i = 0; i < times; i++) {
std::cout << static_cast<std::underlying_type_t<Color>>(color) << ' ';
}
std::cout << std::endl;
}
};
using say_red = say_my_name<Color::Red>;
int main()
{
say_my_name<Color::Yellow>()(3);
say_my_name<Color::Yellow>()();
say_red()(2);
say_red()(); // too few arguments to function
}
如果您不喜欢额外的 ()
,您可以这样做:
using say_red = say_my_name<Color::Red>;
constexpr auto red_say = say_red{};
int main()
{
red_say(2);
red_say(); // too few arguments to function
}
请注意,您也可以使用构造函数代替 operator()
,但使用 operator()
更灵活,因为它允许您 return 一个值。关键只是分两步进行特化和重载解析(特化仿函数,然后使用一个或零个参数调用 operator()
)。