我遇到以下构造的问题:
struct A {
int min_version;
int max_version;
std::vector<int> nodes;
A(std::vector<int> _nodes, int _min_version = 0, int _max_version = MAXINT)
: nodes(_nodes), min_version(_min_version), max_version(_max_version)
{};
};
static std::vector<A> a = list_of<A>
(list_of (1) (2))
;
我遇到编译器错误,2个重载都不能转换所有参数类型(Visual Studio 2013)。但是,当我为一个或两个默认参数添加值时,它编译得很好:
static std::vector<A> a = list_of<A>
(list_of (1) (2), 1)
;
那么,使两个默认参数都起作用的技巧是什么?
答案 0 :(得分:1)
当您将list_of<A>(...)
替换为list_of(A(...))
时,单参数版本的问题变得更加明显:编译器错误变为(GCC):
list.cc: In function ‘int main()’: list.cc:18:30: error: call of overloaded ‘A(boost::assign_detail::generic_list<int>&)’ is ambiguous list_of (A (list_of (1) (2))); ^ list.cc:18:30: note: candidates are: list.cc:11:3: note: A::A(std::vector<int>, int, int) A(std::vector<int> _nodes, int _min_version = 0, int _max_version = INT_MAX) ^ list.cc:6:8: note: A::A(const A&) struct A { ^ list.cc:6:8: note: A::A(A&&)
这是有道理的,有点:通用无类型列表 * 声称可以转换为任何类型;它不会(也可能不会)使用SFINAE来拒绝转换不起作用的类型。
在您的示例中,从无类型列表到A
的转换比从无类型列表到std::vector<int>
到A
的转换更好。那么转换当然不起作用。
当您传递第二个参数时,编译器知道您不可能尝试调用复制构造函数。
我个人的偏好是在构造函数中添加一个伪参数,类似于标准对piecewise_construct_t
的使用:
struct from_vector { };
struct A {
...
A(std::vector<int> _nodes, ...) { ... }
A(from_vector, std::vector<int> _nodes, ...) : this(_nodes, ...) { }
};
然后你可以写
list_of<A>( from_vector(), list_of (1) (2) )
* 当我说“无类型列表”时,我当然意识到Boost实际上为该列表定义了一个类型,并且C ++表达式总是有一个类型。