5

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

#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
}

错误信息:

<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> >)

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

4

2 回答 2

3

我希望有一个更好的答案,但是您可以利用这样一个事实,即使用已定义类型的空括号进行列表初始化比构造函数更喜欢默认构造initializer_list函数。不幸的是,这意味着必须将 的重载func转换为单个参数类型的构造函数的重载集:

using namespace std;
struct parameter {
   // representation left as an exercise - perhaps Boost.Variant?
   parameter(vector<string> v) {}
   parameter(vector<wstring> v) {}
   parameter(initializer_list<string> iv) {}
   parameter(initializer_list<wstring> iv) {}
   parameter() {}  // default constructor - func({}) calls this
};
void func(parameter) {}

如果您不使用string,则可以使用template<typename T> void func(initializer_list<T>)带有empty重载的模板,因为非模板重载优于模板重载,但不幸的是,在您的情况下,字符串文字调用被推断为initializer_list<const char *>,这很难转换为initializer_list<string>.

于 2013-01-30T18:31:03.583 回答
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) {}

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

于 2013-01-30T22:37:02.290 回答