隐式转换操作符T()使用的std :: enable_if模板重载编译失败

问题描述 投票:1回答:2

我写在C ++ 17类,我想超载转换操作符浮动类型,以及一些自定义类型。这里是重复的例子。还有更多的转换,我需要使用模板添加,但如果我能解决这些问题,剩下的应该是相似的。

class A {
};

class B : public A {
};

class C: public A {
};

class Missing {
 public:
  Missing() {}
  Missing(Missing &) = default;

  template<typename T,typename=typename std::enable_if_t<std::is_floating_point_v<T>, T>>
  explicit constexpr operator T() const {
    return static_cast<T>(NAN);
  }

  template<typename T, class = typename std::enable_if_t<std::is_base_of_v<A, T>, T>>
  explicit operator T() const {
    return T();
  }


};

但是在用gcc编译8.2性病= C ++ 17的标志,我得到以下错误:

<source>:25:12: error: 'template<class T, class> Missing::operator T() const' cannot be overloaded with 'template<class T, class> constexpr Missing::operator T() const'

   explicit operator T() const {

            ^~~~~~~~

<source>:20:22: note: previous declaration 'template<class T, class> constexpr Missing::operator T() const'

   explicit constexpr operator T() const {

                      ^~~~~~~~

Compiler returned: 1

我会认为,使用enable_if将阻止运营商超载对于同一类型,但看起来像编译器是不是在看第一遍的enable_if。我不知道我是否有正确的语法。任何帮助,将不胜感激。现在这已经有一段时间。


更新:

尝试更新的运营商

  template<typename T>
  constexpr explicit operator std::enable_if_t<std::is_floating_point_v<T>, T>() const {
    return static_cast<T>(NAN);
  }

  template<typename T>
  explicit operator std::enable_if_t<std::is_base_of_v<A, T>, T>() const {
    return T();
  }

但现在,在尝试投放该类浮动:

int main() {
    Missing m;
    float a = static_cast<float>(m);
}

我得到一个错误:

<source>:34:35: error: invalid static_cast from type 'Missing' to type 'float'

     float a = static_cast<float>(m);
c++ templates c++17 sfinae
2个回答
2
投票

问题是,您声明相同的成员模板两次,用不同的默认参数。所以默认参数,甚至没有看任何实例之前的错误发生。

先冲来解决这将是移动enable_if_t出论点并使其操作的返回类型:

template<typename T>
explicit constexpr operator std::enable_if_t<std::is_floating_point_v<T>, T>>() const ...

但是,这并不工作,因为T是undeduced方面现在。

所以其他的方式,使两个模板不同的是添加一个虚拟参数有一个默认值其中之一。

template<typename T,
         typename = std::enable_if_t<std::is_floating_point_v<T>, T>,
         bool = true>
explicit constexpr operator T() const ...

其他模板应保持原样。

具有不同数量的模板参数的两个模板,他们不再认为是相同的。


2
投票

另一种方法是定义导出模板参数是一个默认的指针:

template
<
  typename T, 
  std::enable_if_t<std::is_floating_point_v<T>>* = nullptr
>
explicit constexpr operator T() const {
  return static_cast<T>(NAN);
}

我觉得这是一个简洁,可靠的方式来选择是否启用方法,运营商和建设者。

© www.soinside.com 2019 - 2024. All rights reserved.