簡體   English   中英

模板中的枚舉 class

[英]Enum inside a templated class

假設我有一個 class Class ,它有一個關聯的枚舉成員Enum 枚舉僅在這個 class 的上下文中才有意義,因此它在其中指定。 然后你可以從 class 之外調用Class::Enum::Something ,這很好。

class Class
{
   public:
      enum class Enum : uchar
      {
          Something
      }
}

但是,如果 class Class是模板化的,則不能執行Class::Enum::Something ,但必須執行Class<T>::Enum::Something (或Class<>::Enum::Something如果T有一些默認值類型)。

template <typename T = double>
class Class
{
   public:
      enum class Enum : uchar
      {
          Something
      }
}

所有TEnum必須相同,因為它只是一個簡單的枚舉,但無論如何始終必須指定T

我的問題是 - 有避免這種情況的聰明方法嗎?

必須了解包裝的枚舉類型對於Class的不同特化是不同的類型。

#include <type_traits>

template <typename T = double>
struct S
{
      enum class E : int { a };
};

static_assert(!std::is_same_v<S<>::E, S<int>::E>);  // !!!

看起來你希望它實際上是相同的類型,在這種情況下你可以將它分解成一個單獨的 class 並使用私有實現 inheritance 通過 class 模板專業化公開它:

#include <type_traits>

namespace detail {
struct Base {
    enum class E : int { a };
};
}  // namespace detail;

template <typename T = double>
struct S : private detail::Base
{
    using Base::E;    
};

static_assert(std::is_same_v<S<>::E, S<int>::E>); // OK

但是,如果您打算將此枚舉作為各種 class 模板專業化的成員(上面的別名聲明)提供,則需要限定您引用的專業化。

S<>::E;
S<int>::E;

您似乎想要解決的根本問題是scoping ,在這種情況下,您可以使用命名空間而不是 class 來包裝關聯的枚舉:

namespace my_lib {

template <typename T = double>
struct S {};

enum class E : int { a };

}  // namespace my_lib

通常將不依賴於 tempalte 參數的所有內容移動到非模板基 class 會更方便:

#include <iostream>

class Base {
   public:
      enum class Enum
      {
          Something
      };

};

template <typename T = double>
class Class : public Base
{
};

int main() {
    std::cout << (Class<>::Enum::Something == Class<int>::Enum::Something);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM