【问题标题】:Any way to fix this type deduction?有什么办法可以解决这种类型的扣除?
【发布时间】:2019-01-11 15:57:57
【问题描述】:

以下情况的类型推导失败。如果我为 someFunc 指定模板参数,它就会编译。我肯定看到这是一个奇怪的案例,但如果我能让它工作就好了。有没有另一种方法来制定它,可以在不提供模板参数的情况下编译? C++17 解决方案很好。

#include <type_traits>

template<typename T>
using choose_arg_type = typename std::conditional<std::is_fundamental<T>::value,T,const T &>::type;

template<typename T>
T someFunc(choose_arg_type<T> arg)
{
    return arg + arg;
}

int main()
{
    auto result = someFunc(0.0);

    return 0;
}

【问题讨论】:

  • 为什么不总是使用const T&amp; ?作为模板/可见代码,如果没有完全内联,我希望编译器以正确的方式传递参数。
  • 我认为编译器可以为您处理此优化。
  • @Jarod42 可能是 OP 不想将引用绑定到基本 constexpr 和 ODR 使用它们?
  • 内联代码时编译器可能会优化,但一般不会,这会导致性能下降。
  • 所以 - 是的......这是关于性能的。我读过的普遍看法是,通过价值传递基本类型的性能更好。一个原因可能是缓存位置。但是这个简单的测试并没有显示出任何区别:quick-bench.com/BXdkUX2YfBBnFg7m2gsOKo0dbkg

标签: c++ templates


【解决方案1】:

template<typename T>
T someFunc(choose_arg_type<T> arg)

T 是依赖类型。因此,这里不会发生类型扣除。您可以通过使用SFINAE 并针对类型是否为基本类型引入一组重载来解决此问题。看起来像

template<typename T, std::enable_if_t<std::is_fundamental_v<T>, bool> = true>
T someFunc(T arg)
{
    return arg + arg;
}

template<typename T, std::enable_if_t<!std::is_fundamental_v<T>, bool> = true>
T someFunc(const T& arg)
{
    return arg + arg;
}

【讨论】:

  • 出于好奇 - 为什么 enable_if_t 使用 bool 而不是默认的 nullptr?少打字:)
  • @SergeyA Yakk 曾表示他在某些编译器中遇到了问题,但使用 booltrue 有效。我喜欢他的建议,因为它强化了我希望 enable_if 的条件为真,以使此重载可用。我实际上并没有看到enable_if_t&lt;...&gt;* = nullptr 的问题,但我已经越来越喜欢这种方式了。
  • 我很想知道问题是什么。
  • 我不确定。我知道使用 enable_if_t&lt;...&gt;* = 0 存在一个已知问题,但我没有看到任何关于 enable_if_t&lt;...&gt;* = nullptr 的信息。
  • @SergeyA 默认为void
【解决方案2】:

不,choose_arg_type&lt;T&gt; 处于非推断上下文中。已经有不少重复了。

但是,您可以有两个重载,并根据类型启用 SFINAE。

【讨论】:

    猜你喜欢
    • 2014-05-24
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多