【问题标题】:Issue with template argument deduction模板参数推导问题
【发布时间】:2020-09-17 17:07:43
【问题描述】:

我有一个非常简单的模板问题。 我想要一些可以处理标量和向量的数学函数。对于参数,我希望我的标量通过副本传递,我的向量通过引用传递。 所以我最终使用了一个模板化的辅助结构。

但是当我使用我的函数时,编译器无法自行推断出模板参数。 我不知道我做错了什么,或者我应该做些什么不同,或者这种方法是否从一开始就注定要失败^^'。

这是一个例子:

#include <type_traits>

template <typename T>
struct CopyOrConstRef
{
    using Type = std::conditional_t<
                    std::is_scalar<T>::value,
                    T,
                    const std::remove_reference_t<T>&
                 >;
};
template <typename T>
using CopyOrConstRef_t = typename CopyOrConstRef<T>::Type;

template <typename T>
T Lerp(CopyOrConstRef_t<T> _a, CopyOrConstRef_t<T> _b, const float _factor)
{
    return (_a * (1.f - _factor)) + (_b * _factor);
}

int main()
{
    Lerp(0.f, 1.f, 0.5f); // does not work :'(
    Lerp<float>(0.f, 1.f, 0.5f); // works as intended

    return 0;
}

带有错误消息(在 msvc 上):

error C2672: 'Lerp': no matching overloaded function found
error C2783: 'T Lerp(CopyOrConstRef<T>::Type,CopyOrConstRef<T>::Type,const float)': could not deduce template argument for 'T'

【问题讨论】:

  • 模板参数推导并不是这样工作的。它始终匹配确切的类型,无需任何转换。您正在传递float,该函数只会采用某种形式的CopyOrConstRef&lt;...&gt;,因此推导失败。
  • 那么,我一开始就注定了? :,D 有什么方法可以实现我想要做的吗?
  • 通过 const ref 传递 float 通常不是问题,尤其是使用模板时。无论如何,函数调用都有可能被内联。

标签: c++ templates template-argument-deduction


【解决方案1】:

这不起作用,因为T(即CopyOrConstRef_t&lt;T&gt;)在Lerp的参数列表中的所有用法都在non-deduced contexts中:

未推断的上下文是:

使用限定 ID 指定的类型的嵌套名称说明符。


这是来自参考的example

如果模板参数仅用于非推导上下文,则它们不参与模板实参推导。例如,

template<int i, typename T>
T deduce(typename A<T>::X x,    // T is not deduced here
        T t,                    // but T is deduced here
        typename B<i>::Y y);    // i is not deduced here

你的例子是一样的,除了没有可以推导出来的参数,而且你有一个参数的别名模板(它不会改变任何东西)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    相关资源
    最近更新 更多