10

我知道常见问题的答案如何指定指向重载函数的指针?:无论是赋值还是强制转换,所有其他 C++ 教程都会将这样的字符串大写(give 或 take 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);

它巧妙地选择<cctype>std::toupper.

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

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

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

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

4

2 回答 2

5

这很有趣,我正在做类似的事情。我发现最好的方法是使用如下的 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!
于 2011-07-10T22:32:07.960 回答
0

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

typedef char (*LocaleToUpper)(char, const std::locale&) ;
char (*fp2)(char, const std::locale&) = (LocaleToUpper)toupper;
于 2011-07-08T22:52:22.633 回答