【发布时间】:2022-01-15 08:03:51
【问题描述】:
在下面的代码中,X x1{{100,5.55}, "abc"} 编译失败(“候选模板被忽略:无法推断模板参数 'T1'”)。
我认为这是因为模板推导不考虑隐式转换,因此编译器不会将第一个参数视为 std::pair。
有什么方法可以使X x1{{100,5.55}, "abc"} 语法起作用吗?我想避免在参数中显式使用 std::pair,因为我正在重构一个大型代码库,该表达式在许多地方都使用。
(在当前代码中,构造函数没有模板化,因为它使用 std::variant 创建了一个综合类,该类使用 int、double、std::string 等的隐式构造函数来处理多种类型。我正在尝试替换这个类使用保留底层数据类型的模板化构造函数,以提高类型安全性。)
#include <utility>
struct X
{
template <class T1, class T2> X(std::pair<T1,T2>, const char*){}
};
int main()
{
X x{std::pair{100,5.55}, "abc"}; // OK
// X x1{{100,5.55}, "abc"}; // Compile error
}
【问题讨论】:
-
我的猜测是
{100, 5.55}被推导出为std::initializer_list,而std::pair一定没有对应的构造函数。 -
@Mansoor 我认为它根本没有被推断出来。据我所知,这是non-deduced context。
-
@Mansoor 你错了。 OP已经提到了代码不起作用的正确原因,即模板参数推导中不考虑隐式转换。
-
添加
X(std::pair<int,double>, const char*){}重载:) -
@rustyx 这导致
{5.5, 1}对通过std::pair<int, double>构造函数。 IMO 非常容易出错。