gpt4 book ai didi

C++ 模板重载 - 调用了错误的函数

转载 作者:搜寻专家 更新时间:2023-10-31 00:05:09 24 4
gpt4 key购买 nike

        template<typename T> T* Push(T* ptr);
template<typename T> T* Push(T& ref);
template<typename T, typename T1> T* Push(T1&& ref);

我有

        int i = 0;
Push<int>(i);

但是编译器称它有歧义。怎么这么暧昧第二个函数显然是首选匹配项,因为它更专业。特别是因为 T1&& 不会绑定(bind)到左值,除非我明确转发/移动它。

抱歉 - 我是一个整数。否则,这个问题就没有意义了,我认为人们会推断出它,因为它通常是循环迭代器。

最佳答案

如果i是一个 int,则第一个不可行。剩下最后两个。然后,扣除i ,第二个和第三个都产生相同的重载解析函数类型(都是 int& 作为参数)。所以你必须依赖偏序。

但是,部分排序无法区分它们。对于函数调用部分排序上下文,仅参数用于确定顺序(并且不考虑示例中的返回类型),并且从它们中剥离任何引用修饰符。因此,您将成功地在两个方向上从一个参数类型推导另一个参数类型 - 两种参数类型至少分别与其他参数一样专门化。并且都没有应用 const,因此两者都不比另一个更专业。

有一个问题报告占位符旨在澄清在部分排序期间与右值/左值引用困难相关的任何事情。参见 this usenet question了解详情。

如果两者中的任何一个应该更专业,我会说它应该是第一个。毕竟,它比另一个接受更少的参数(另一个是潜在的完美转发器)。


Especially since the T1&& won't bind to an lvalue unless I explicitly forward/move it.

实际上,它会接受任何东西。具有 T&& 类型的参数在模板中将切换到“完美转发推导模式”,这将推导 T如果它是右值,则添加到参数的类型,并将左值引用修饰符添加到 T 的类型如果它是一个左值。因此,如果参数是左值,则结果参数类型为 T& &&折叠到 T& ,它接受左值很好(就像你的情况一样)。

再看一眼,您似乎想做的是重载一个通过移动对象来获取对象的函数。但这行不通,因为对 T&& 进行了特殊扣除。 (见下文)。只需删除第一个函数并将代码编写为

template<typename T, typename T1> T* Push(T1&& ref) {
/* for lvalues, T1 is U& and rvalues it is U, with U being the
* argument type. */
T t1(std::forward<T1>(ref));

/* whatever needs to be done ... */
}

这将移动构造t1如果参数是右值,则复制 ref如果参数是左值或者如果 T没有移动构造函数。这只是一个示例,根据您的实际用例,它可能不是您实际应该做的。我也不确定为什么这里有两种模板参数类型。我建议摆脱 T ,然后说 typename remove_reference<T1>::type *相反,返回类型。这样你就可以从论证推导中获益。

关于C++ 模板重载 - 调用了错误的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2984729/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com