将带有默认值的函数作为忽略它们的参数传递
Passing function with defaults as argument ignoring them
我需要将表示 T
s 向量的字符串转换为相应的向量。
我的问题是我想传递一个简单的参数:转换器函数。以下是split
:
template <class T>
auto split(const std::string &s, const std::function<T(const std::string&)> &convert, char sep = ',') -> std::vector<T>
{
std::stringstream ss(s);
std::vector<T> result;
while (ss.good())
{
std::string substr;
std::getline(ss, substr, sep);
if (!substr.empty())
result.push_back(convert(substr));
}
return result;
};
它在传递标准函数(如 std::stoi
)时无法编译,因为 std::stoi
的默认参数int stoi(const string& __str, size_t* __idx = 0, int __base = 10);
auto q = split<int>(subs, std::stoi);
error: no matching function for call to 'split'
auto q = split<int>(subs, std::stoi);
^~~~~~~~~~
显然,我可以通过使用lambda函数来欺骗编译器:
auto q = split<std::size_t>(subs, [](const std::string &s){ return std::stoul(s); });
有没有一个元编程技巧可以让我以某种方式忽略默认参数?
编辑:在这种情况下,这实际上没有帮助。我离开它是因为它在其他一些情况下很有用,例如如果你有一个函数返回可转换为T
的东西,但它没有解决stoi
的任何问题。
不要显式指定函数的类型。让convert
成为任何类型;如果您尝试传递无法在std::string
上调用或未返回可转换为T
的内容,则会收到错误。没有理由限制超出此范围的类型,除非您有明确的理由需要它是该特定类型,而在这种情况下,您不需要。
因此,您可以将函数声明为
template <class T, class F>
auto split(const std::string &s, const F&& convert, char sep = ',') -> std::vector<T>
#define RETURNS(...)
noexcept(noexcept(__VA_ARGS__))
-> decltype( __VA_ARGS__ )
{ return __VA_ARGS__; }
#define OVERLOADS_OF(...)
[](auto&&...args)
RETURNS( __VA_ARGS__( decltype(args)(args)... )
此宏允许您获取函数的名称并生成包含其重载的 lambda。
auto q = split<std::size_t>( subs, OVERLOADS_OF(std::stroul) );
这很好,很简洁。
默认参数只能通过调用函数实际名称的()
来访问,将名称"移动到不同上下文中的唯一方法是将其作为文本填充到 lambda 中。
顺便说一句,@barry有一个 c++2a 建议将上面的RETURNS(X)
替换为 lambda 的=> X
。 我不知道目前维护的替换OVERLOADS_OF
宏的提议(不久前有一个)。
可能 c++2a 反射提案将允许您访问函数名称的默认参数和重载集,然后花哨的元编程将允许您在没有宏的情况下生成OVERLOADS_OF
。
相关文章:
- 如何在C++中提供模板化函数作为另一个函数的参数,默认值?
- 如何通过 C++ 中的函数参数传递初始值设定项列表的固定大小的初始值设定项列表?
- 对 const 引用参数使用默认值会导致崩溃
- C++:通过函数参数传递的值给出不同的结果
- 指针参数的默认值
- 我可以在哪里放置参数的默认值
- 如何在C++中设置std::list参数的默认值?
- 模板模板参数用作其他参数的默认值
- 模板模板参数和默认值
- 模板函数参数的默认值
- 根据模板参数的默认值启用模板参数类型的自动扣除
- 为什么在指定其所有模板参数具有默认值的模板类时需要<>?
- 具有一个参数和默认值的类模板
- 是否可以将`constexpr`模板变量作为正式模板参数的默认值
- 了解如何声明模板参数的默认值
- 模板函数、功能参数的默认值
- 如何为函数中的矢量参数提供默认值
- 显式使用类模板实例化中某些参数的默认值
- 如何使用命名变量定义常量右值引用参数的默认值
- 为通过引用传递的参数指定默认值