情况如:
#include <utility>
#include <typeinfo>
#include <iostream>
struct C1
{
char const* str;
template <typename T> operator T() const { std::cout << "Convert to " << typeid(T).name() << "\n"; return {}; }
};
struct C2
{
C2(C1 const&) { std::cout << "C2(C1)\n"; }
C2(std::initializer_list<std::pair<char const*, int>>) { std::cout << "C2(list)\n"; }
};
int main()
{
C1 c1{};
C2 c2{c1};
}
输出表示正在调用C2(list)
。
我希望C2(C1)
为C1
参数调用,但我需要std :: initializer list的参数保持可推导和可转换,我不能用variadic-templated版本替换它。我只想控制施工顺序,但这里// 2甚至不是模板。假设类型std :: pair可以在正常条件下反序列化。可以使用C ++ 14
答案 0 :(得分:0)
您可以使用显式关键字来阻止构造函数进行隐式类型转换:
explicit C2(std::initializer_list<std::pair<char const*, int>>) {} // 2
答案 1 :(得分:0)
以下为样式C2(C1)
和{...}
选择({...})
样式(在严格的C ++ 11标准中,对于({...})
样式,它将选择第二种,因为C1
是一个聚合,并且适用了特殊规则。对于更新的标准,情况不再是这种情况。)。这可以使第二个构造函数不再是初始化构造函数。
template<typename T>
struct id { typedef T type; };
struct C1 {
char const* str;
template <typename T> operator T() const
{ std::cout << "Convert to " << typeid(T).name() << "\n"; return {}; }
};
struct C2 {
C2(C1);
template<typename T = std::initializer_list<std::pair<char const*, int>>>
C2(typename id<T>::type);
};
int main() {
C1 c1{};
C2 c2{c1};
C2 c21({c1});
}