C++ 将默认值作为参数传递函数,忽略它们

C++ 将默认值作为参数传递函数,忽略它们,c++,c++11,templates,c++2a,C++,C++11,Templates,C++2a,我需要将表示Ts的向量的字符串转换为相应的向量 我的问题是我想传递一个简单的参数:converter函数。以下是拆分: template <class T> auto split(const std::string &s, const std::function<T(const std::string&)> &convert, char sep = ',') -> std::vector<T> { std::strings

我需要将表示
T
s的向量的字符串转换为相应的向量

我的问题是我想传递一个简单的参数:converter函数。以下是
拆分

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;
};
显然,我可以通过使用lambda函数欺骗编译器:

auto q = split<std::size_t>(subs, [](const std::string &s){ return std::stoul(s); });
auto q=split(subs,[](const std::string&s){return std::stoul(s);});

是否有一种元编程技巧允许我忽略默认参数?

编辑:在这种情况下,这实际上没有帮助。我之所以离开它,是因为它在其他一些情况下很有用,例如,如果您有一个函数返回了可转换为
T
的内容,但它没有解决
stoi
的任何问题


不要显式指定函数的类型。让
转换
为任何类型;如果您尝试传递无法在
std::string
上调用的内容,或者无法返回可转换为
t
的内容,则会出现错误。没有理由将类型限制在该范围之外,除非您特别有理由认为它需要是该特定类型,在本例中,您没有理由这样做

因此,您可以将函数声明为

template <class T, class F>
auto split(const std::string &s, const F&& convert, char sep = ',') -> std::vector<T>
模板
自动拆分(常量std::string&s,常量F&&convert,char sep=',')->std::vector
此宏允许您获取函数名并生成包含其重载的lambda

auto q = split<std::size_t>( subs, OVERLOADS_OF(std::stroul) );
auto q=split(subs,重载(std::stroul));
这是好的和简洁的

默认参数只能通过对函数的实际名称调用
()
来访问,而将名称“移动”到其他上下文中的唯一方法是将其作为文本填充到lambda中

另一方面,@barry建议用
=>X
替换上述lambdas的
RETURNS(X)
。我不知道目前有一个建议要替换
宏的
重载(不久前有一个)


反射方案可能会允许您访问默认参数和函数名的重载集,而奇特的元编程将允许您在不使用宏的情况下生成
重载。

默认参数是什么意思?您明确指定要拆分
split
。我的意思是
std::stoi
实际上有默认参数:签名是
intstoi(const string&\uu str,size\u t*\uu idx=0,int\uu base=10)。我希望忽略默认签名。如果您可以避免使用std::function,它将使您的生活更轻松。(一个模板化的函数参数会更好。)@yakkugh,是的,重载。我不认为SFINAE真的能处理这个问题,所以我不知道是否有可能让它在没有宏的情况下在呼叫站点上透明地工作,但我可能错了,甚至没有过载。如果重载为零,传入的函数指针或引用(必须解析为要传入的对象)将不会携带默认参数。所以在通话时它不会起作用。@yack你是对的,我的回答在某些情况下有用,但这次不行。
#define RETURNS(...) \
  noexcept(noexcept(__VA_ARGS__)) \
  -> decltype( __VA_ARGS__ ) \
  { return __VA_ARGS__; }

#define OVERLOADS_OF(...) \
  [](auto&&...args) \
  RETURNS( __VA_ARGS__( decltype(args)(args)... )
auto q = split<std::size_t>( subs, OVERLOADS_OF(std::stroul) );