如何重载空的 std::initializer_list?

rsk*_*k82 5 c++ overloading initializer-list c++11

在这里,我有一系列重载函数,它们以向量或初始化列表作为输入。我想处理客户端代码输入空的初始化列表时的特殊情况。问题是编译器无法确定在这样的空列表中应该有哪些数据。所以我的问题是我如何在函数声明中解决这种情况。

#include <string>
#include <vector>

using namespace std;
void func(vector<string> v) { }
void func(vector<wstring> v) { }
void func(initializer_list<string> iv) {}
void func(initializer_list<wstring> iv) {}

int main() {
  using namespace std;
  func({"apple", "banana"});
  func({L"??", L"??"});
  func({}); // special case
}
Run Code Online (Sandbox Code Playgroud)

错误信息:

<stdin>: In function 'int main()':
<stdin>:14:10: error: call of overloaded 'func(<brace-enclosed initializer list>)' is ambiguous
<stdin>:14:10: note: candidates are:
<stdin>:5:6: note: void func(std::vector<std::basic_string<char> >)
<stdin>:6:6: note: void func(std::vector<std::basic_string<wchar_t> >)
<stdin>:7:6: note: void func(std::initializer_list<std::basic_string<char> >)
<stdin>:8:6: note: void func(std::initializer_list<std::basic_string<wchar_t> >)
Run Code Online (Sandbox Code Playgroud)

void func(initializer_list<void> iv) {}- 没有效果。我不知道如何正确声明它。

Joh*_*itb 3

仅通过参数无法区分这一点。不过,您可以将其中一个作为模板,这会导致成本更高,并且对于重载解析而言不太可取

void func(vector<string> v) { }
void func(vector<wstring> v) { }
template<typename = void>
void func(initializer_list<string> iv) {}
void func(initializer_list<wstring> iv) {}
Run Code Online (Sandbox Code Playgroud)

现在调用func({})将优先选择最后一个函数而不是函数模板。请注意,func({"hello", "world"})与非模板向量获取函数相比,仍然更喜欢函数模板,因为参数转换成本比候选是否是从模板合成的更重要。