【问题标题】:Deduce type of a member of a template argument object推断模板参数对象成员的类型
【发布时间】:2016-02-24 15:52:58
【问题描述】:

有这个功能:

template <typename T>
T operator-(const T vector)
{}

我想强制 T 具有 xy 成员,并且它们是算术的。 我试图通过std::declval&lt;T&gt;

template <typename T,
  typename = typename 
    std::enable_if<std::is_arithmetic<std::declval<T>.x>::value>::type,
  typename = typename 
    std::enable_if<std::is_arithmetic<std::declval<T>.y>::value>::type>
T operator-(const T vector)
{}

但我得到的只是,无法推断出类型:error: insufficient contextual information to determine type。模板参数对象的成员类型可以推导出来吗?

【问题讨论】:

  • 语法std::declval&lt;T&gt;.x只能用于对象,不能用于类型。
  • @RSahu:没错。我没有注意到这一点。谢谢。那么是否有可能在编译时找出传递对象的成员类型呢?
  • 我尝试使用std::is_arithmetic&lt;typename T::x&gt;::value,它可以编译,但它似乎不起作用。
  • decltype(std::declval&lt;T&gt;().x),或decltype(T::x)
  • @T.C.后者可能会无意中对重载运算符点的 C++17 类给出错误否定。 :o)

标签: c++ templates c++14 type-deduction


【解决方案1】:

我认为您实际上并不想强制它们是算术的。您希望函数模板主体中的关键表达式格式正确。在这种情况下,请按照

template <typename T>
auto operator-(const T& vector)
  -> decltype(void(x - vector.x), void(y - vector.y), vector)
{/* ... */}

如果您希望坚持使用正确版本的代码,将 decltype(std::declval&lt;T&gt;().x)decltype(T::x) 替换为 std::declval&lt;T&gt;.xy 同上)就足够了:

template <typename T,
  typename = std::enable_if_t<std::is_arithmetic<decltype(T::x)>{}>,
  typename = std::enable_if_t<std::is_arithmetic<decltype(T::x)>{}>>
T operator-(const T vector)
{}

【讨论】:

  • 我确实想确保它们是算术的。我需要否定他们的价值观。如果它们不是算术的,那就没有意义了。还是我在这里遗漏了什么?
  • @Dundee:复数/有理数不是算术,但对它们取反是有意义的。
  • @Dundee 一元运算符- 可以重载。
  • @Jarod42:你是对的。幸运的是,这些不适合我的用例。
  • @Columbo:是的,我知道。它更多地与我希望如何使用库有关。无论如何,感谢您提供这两种选择。你太棒了:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2012-06-13
  • 2015-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多