未调用 C++ enable_if 类特化

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

我有以下尝试使用

enable_if
来实例化
A
类的 2 个不同专业化的示例,但我不正确理解它,因为它们没有被调用,有什么建议吗?

#include <type_traits>
#include <iostream>


class SC1 {
public:
  SC1() {
    std::cout << "SC1\n";
  }
};

class SC2 {
 public:
  SC2() {
    std::cout << "SC2\n";
  }

  void f() {};
};

template <class T, typename TC1 = void, class TC2 = void>
class A  {
public :
  A() {
    std::cout << "default A\n";
  };
};


template <class T>
class A <T, typename std::enable_if_t<T::SC1_ENABLE, typename T::EN>, void> : public  T::EN {
  static_assert(!std::is_same<typename T::EN, SC1>::value);
public:
    A() {
      std::cout << "1 type is " << typeid(typename std::enable_if_t<T::SC1_ENABLE>).name() << "\n";
  }
};


template <typename T>
class A <T, void,  typename std::enable_if_t<T::SC2_ENABLE,  typename T::EN>> : public T::EN {
public:
  A() {
    static_assert(std::is_same<typename T::EN, SC2>::value);    
    //std::cout << "2 type is " << typeid(typename std::enable_if_t<T::SC2_ENABLE>).name() << "\n";
  }
  
};

  
  struct T1 {
    static constexpr bool SC1_ENABLE = false;
    static constexpr bool SC2_ENABLE = false;
  };

  struct T2 {
    static constexpr bool SC1_ENABLE = true;
    static constexpr bool SC2_ENABLE = false;
    typedef SC1 EN;
  };

  struct T3 {
    static constexpr bool SC2_ENABLE = true;
    static constexpr bool SC1_ENABLE = false;
    typedef SC2 EN;
  };

int main() {
  //    std::enable_if_t<T3::SC2_ENABLE,T3::EN>();

  A<T3>();
  A<T2>();

}

我尝试了它的不同变体,使用 GCC 使用 c++ std 20 编译它,并且仅调用

A
的默认实现。

c++ templates enable-if
1个回答
0
投票

您使用了

std::enable_if
错误。

在主模板中,您使用

typename TC1 = void
作为模板参数(顺便说一下,可以将其简化为
typename = void
)。 为了让
A<T2>()
(相当于
A<T2, void, void>()
)使用第一个部分特化,部分特化也必须有
void

但是,您使用的是

typename std::enable_if_t<T::SC1_ENABLE, typename T::EN>
,这是替换后的
T::EN
类型,因此这永远不会匹配。 一旦你写了它就起作用了:

std::enable_if_t<T::SC1_ENABLE>

请注意,

void
是第二个模板参数的默认参数,
typename
是不必要的。

但是,这将放弃

T::EN
必须是类型的要求,因此您可以编写如下内容:

template <typename>
inline constexpr bool tru = true;

// ...
template <class T>
class A <T, std::enable_if_t<T::SC1_ENABLE && tru<typename T::EN>, void> : public T::EN {

还请记住,针对不同的要求使用两个单独的

void
不会在它们之间强加某种顺序,这可能会在您面前爆炸。 请参阅为类型特征排序多个 std::void_t 部分特化的可靠方法以获得可靠的解决方案

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