为什么对重载函数的调用不明确?
Why is this call to the overloaded function ambiguous?
考虑这个程序-
#include <string>
#include <vector>
#include <set>
void fun(const std::string& val) {
}
void fun(std::vector<std::string> val) {
}
int main()
{
std::set<std::string> example;
fun({std::begin(example), std::end(example)});
}
在编译时,我遇到了这些错误-
prog.cc: In function 'int main()':
prog.cc:13:49: error: call of overloaded 'fun(<brace-enclosed initializer list>)' is ambiguous
13 | fun({std::begin(example), std::end(example)});
| ^
prog.cc:4:6: note: candidate: 'void fun(const string&)'
4 | void fun(const std::string& val) {
| ^~~
prog.cc:7:6: note: candidate: 'void fun(std::vector<std::__cxx11::basic_string<char> >)'
7 | void fun(std::vector<std::string> val) {
| ^~~
我知道 std::string
有一个构造函数重载,它接受一个 initializer_list
就像这样-
basic_string( std::initializer_list<char> ilist,
const Allocator& alloc = Allocator() );
和 std::vector<std::string>
有一个看起来像这样的重载-
vector( std::initializer_list<std::string> init,
const Allocator& alloc = Allocator() );
所以,很明显这两种方法在类型上有所不同。一个接收 char
类型的 initializer_list
,另一个接收 std::string
.
类型
在我的代码中,当我传递字符串的初始化列表时,我将 2 个迭代器传递给一组字符串。
即便如此,为什么编译器将此标记为不明确的调用?
编译器发现对以下两个构造函数的调用不明确(请注意,它们都不采用初始化列表):
template <class InputIt>
std::vector::vector (InputIt first, InputIt last, const Allocator& alloc = Allocator());
和
template <class InputIt>
std::string::string (InputIt first, InputIt last, const Allocator& alloc = Allocator());
现在,如果您实际使用这些迭代器参数调用 std::string
构造函数,您会得到一个错误,因为它们不会取消对 char 的引用。但是由于该检查不是函数声明的一部分(例如通过 SFINAE),您会收到歧义错误。
考虑这个程序-
#include <string>
#include <vector>
#include <set>
void fun(const std::string& val) {
}
void fun(std::vector<std::string> val) {
}
int main()
{
std::set<std::string> example;
fun({std::begin(example), std::end(example)});
}
在编译时,我遇到了这些错误-
prog.cc: In function 'int main()':
prog.cc:13:49: error: call of overloaded 'fun(<brace-enclosed initializer list>)' is ambiguous
13 | fun({std::begin(example), std::end(example)});
| ^
prog.cc:4:6: note: candidate: 'void fun(const string&)'
4 | void fun(const std::string& val) {
| ^~~
prog.cc:7:6: note: candidate: 'void fun(std::vector<std::__cxx11::basic_string<char> >)'
7 | void fun(std::vector<std::string> val) {
| ^~~
我知道 std::string
有一个构造函数重载,它接受一个 initializer_list
就像这样-
basic_string( std::initializer_list<char> ilist,
const Allocator& alloc = Allocator() );
和 std::vector<std::string>
有一个看起来像这样的重载-
vector( std::initializer_list<std::string> init,
const Allocator& alloc = Allocator() );
所以,很明显这两种方法在类型上有所不同。一个接收 char
类型的 initializer_list
,另一个接收 std::string
.
在我的代码中,当我传递字符串的初始化列表时,我将 2 个迭代器传递给一组字符串。
即便如此,为什么编译器将此标记为不明确的调用?
编译器发现对以下两个构造函数的调用不明确(请注意,它们都不采用初始化列表):
template <class InputIt>
std::vector::vector (InputIt first, InputIt last, const Allocator& alloc = Allocator());
和
template <class InputIt>
std::string::string (InputIt first, InputIt last, const Allocator& alloc = Allocator());
现在,如果您实际使用这些迭代器参数调用 std::string
构造函数,您会得到一个错误,因为它们不会取消对 char 的引用。但是由于该检查不是函数声明的一部分(例如通过 SFINAE),您会收到歧义错误。