为什么我可以将 boost map_list_of 传递给接受映射而不是构造函数的函数?
Why can I pass a boost map_list_of to a function that takes a map, but not a constructor?
我正在尝试构造一个对象,该对象使用 std::map
作为参数,方法是使用 boost map_list_of
将地图内容传递给它。
这会产生编译错误,但是,当我尝试对采用 std::map
的常规函数执行相同操作时,它编译正常!
#include <map>
#include <boost/assign.hpp>
struct Blah
{
Blah(std::map<int, int> data) {}
};
void makeBlah(std::map<int, int> data) {}
int main()
{
Blah b(boost::assign::map_list_of(1, 2)(3, 4)); // Doesn't compile.
makeBlah(boost::assign::map_list_of(1, 2)(3, 4)); // Compiles fine!
}
我得到的编译错误是:
error: call of overloaded ‘Blah(boost::assign_detail::generic_list<std::pair<int, int> >&)’ is ambiguous
note: candidates are: Blah::Blah(std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >)
note: Blah::Blah(const Blah&)
有什么歧义,为什么它不影响常规函数 makeBlah,据我所知,它与 Blah 构造函数具有相同的签名?
除了创建一个 makeBlah
函数来构造一个 Blah
的对象之外,还有没有更好的方法来实现这一点,看起来我必须这样做?
(顺便说一句,我在使用 map_list_of
的单元测试中执行此操作以使测试输入数据创建更具可读性)
map_list_of
不会创建容器,但会创建
anonymous list which can be converted to any standard container
转换是通过模板用户定义的转换运算符完成的:
template< class Container >
operator Container() const;
所以在构造函数的上下文中,它无法推断是转换为 map<int, int>
还是 Blah
。为避免这种情况,例如,您可以添加一个虚拟构造函数参数:
class Blah
{
public:
Blah(std::map<int, int> data, int)
{
}
};
void makeBlah(std::map<int, int> data)
{
}
void myTest()
{
Blah b(boost::assign::map_list_of(1, 2)(3, 4), 0);
makeBlah(boost::assign::map_list_of(1, 2)(3, 4));
}
有了makeBlah
你就不会有这样的歧义了。
或者,您可以将列表类型作为构造函数参数,然后在 Blah
:
中使用它
class Blah
{
public:
Blah(decltype(boost::assign::map_list_of(0, 0)) data)
: m(data.to_container(m))
{
}
std::map<int, int> m;
};
自从 c++11 出现以来,boost::assign
变得不那么引人注目了。
Blah b({{1, 2},{3, 4}});
应该做。
我正在尝试构造一个对象,该对象使用 std::map
作为参数,方法是使用 boost map_list_of
将地图内容传递给它。
这会产生编译错误,但是,当我尝试对采用 std::map
的常规函数执行相同操作时,它编译正常!
#include <map>
#include <boost/assign.hpp>
struct Blah
{
Blah(std::map<int, int> data) {}
};
void makeBlah(std::map<int, int> data) {}
int main()
{
Blah b(boost::assign::map_list_of(1, 2)(3, 4)); // Doesn't compile.
makeBlah(boost::assign::map_list_of(1, 2)(3, 4)); // Compiles fine!
}
我得到的编译错误是:
error: call of overloaded ‘Blah(boost::assign_detail::generic_list<std::pair<int, int> >&)’ is ambiguous
note: candidates are: Blah::Blah(std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >)
note: Blah::Blah(const Blah&)
有什么歧义,为什么它不影响常规函数 makeBlah,据我所知,它与 Blah 构造函数具有相同的签名?
除了创建一个 makeBlah
函数来构造一个 Blah
的对象之外,还有没有更好的方法来实现这一点,看起来我必须这样做?
(顺便说一句,我在使用 map_list_of
的单元测试中执行此操作以使测试输入数据创建更具可读性)
map_list_of
不会创建容器,但会创建
anonymous list which can be converted to any standard container
转换是通过模板用户定义的转换运算符完成的:
template< class Container >
operator Container() const;
所以在构造函数的上下文中,它无法推断是转换为 map<int, int>
还是 Blah
。为避免这种情况,例如,您可以添加一个虚拟构造函数参数:
class Blah
{
public:
Blah(std::map<int, int> data, int)
{
}
};
void makeBlah(std::map<int, int> data)
{
}
void myTest()
{
Blah b(boost::assign::map_list_of(1, 2)(3, 4), 0);
makeBlah(boost::assign::map_list_of(1, 2)(3, 4));
}
有了makeBlah
你就不会有这样的歧义了。
或者,您可以将列表类型作为构造函数参数,然后在 Blah
:
class Blah
{
public:
Blah(decltype(boost::assign::map_list_of(0, 0)) data)
: m(data.to_container(m))
{
}
std::map<int, int> m;
};
自从 c++11 出现以来,boost::assign
变得不那么引人注目了。
Blah b({{1, 2},{3, 4}});
应该做。