【问题标题】:How do I use overloaded functions with default arguments in algorithms?如何在算法中使用带有默认参数的重载函数?
【发布时间】:2011-09-30 00:40:57
【问题描述】:

我知道常见问题的答案How do I specify a pointer to an overloaded function?:无论是赋值还是强制转换,其他所有 C++ 教程都将这样的字符串大写(给或取static_cast):

transform(in.begin(), in.end(), back_inserter(out), (int(*)(int)) std::toupper);

或者像这样:

int (*fp)(int) = std::toupper;
transform(in.begin(), in.end(), back_inserter(out), fp);

巧妙地选择了std::toupper<cctype> 重载。

但这引出了一个问题:如何以类似的方式选择<locale> 重载?

char (*fp2)(char, const std::locale&) = std::toupper;
transform(in.begin(), in.end(), back_inserter(out), fp2);
// error: too few arguments to function

或者,更实际地,考虑有人尝试在算法中使用 C++11 std::stoi 将字符串向量转换为整数向量:stoi 有两个重载(string/wstring ),每个都有两个额外的默认参数。

假设我不想 explicitly bind 所有这些默认值,我相信如果不将此类调用包装在辅助函数或 lambda 中,就不可能做到这一点。是否有一个提升包装器或 TMP 魔法可以以完全通用的方式为我做这件事?可以编写像 call_as<char(char)>(fp2) 或更可能是 call_as<int(const std::string&)>(std::stoi) 这样的包装器吗?

【问题讨论】:

  • 你能在你的transform 命令中使用一个lambda吗?最简单、最干净。
  • 我写了一条评论并删除了关于 bind 已经是您正在寻找的包装器的评论。然后我想到你必须提供默认值来绑定,从而重新定义它们。
  • 在考虑如何通过模板混淆代码之前,最好先搞清楚算法。所以,从算法开始。如果存在除 EOF 值之外的否定参数,std::toupper 调用将产生未定义行为。
  • 你可以做auto *x = std::toupper<char>;。这看起来要短得多。

标签: c++ c++11 overloading default-arguments


【解决方案1】:

这很有趣,我正在做类似的事情。我发现最好的方法是使用如下的 lambdas,否则,你必须使用 typedef 来获得正确的重载和 std::bind 来摆脱语言环境,或者不使用语言环境。但是,这更干净:

static const std::locale loc;
transform(in.begin(), in.end(), back_inserter(out), [&loc](char c) {
  return std::toupper(c, loc);
});

我使用静态来节省每次重新分配的工作量。

或者你可以得到一个 typedef 然后做:

 std::bind((LocaleCompare)std::toupper, std::placeholders::_1, loc); // UGLY!

【讨论】:

    【解决方案2】:

    您应该创建该函数指针类型的 typedef,然后强制转换该函数。

    typedef char (*LocaleToUpper)(char, const std::locale&) ;
    char (*fp2)(char, const std::locale&) = (LocaleToUpper)toupper;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多