簡體   English   中英

使用C ++ std :: enable_if和普通函數?

[英]Using C++ std::enable_if with a normal function?

假設我有一個枚舉:

typedef enum {
  Val1,
  Val2,
  Val3,
  Val4
} vals;

並且函數check(vals x)返回一個布爾值,指示val是否在vals中的特定值子集中。

bool check(vals x) {
  switch(x) {
  case Val1:
  case Val3:
    return true;
  }
  return false;
}

我想使用這個函數作為enable_if的條件(正如你所看到的那樣,它不是一個函數,取決於運行時),讓用戶只使用帶有類模板的那些值。

class MyClass<vals v> {

}

PS:我需要模板來為類的方法進行特化,具體取決於模板值。

在C ++ 14中,只需聲明函數constexpr並保持實現不變。

在C + 11中,您需要將其更改為單個return語句:

constexpr bool check(vals x) {
    return x == Val1 || x == Val3;
}

您既不需要函數也不需要enable_if來執行此操作。
這是一個例子:

enum class vals {
    Val1,
    Val2,
    Val3,
    Val4
};

template<vals v, bool = (v == vals::Val1 || v == vals::Val3)>
class MyClass;

template<vals v>
class MyClass<v, true> { };

int main() {
    MyClass<vals::Val1> ok;
    // MyClass<vals::Val2> ko;
}

這個解決方案實際上有一個問題: MyClass<vals::Val2, true> ok; 是一個有效的聲明。
無論如何,如果它適合,主要取決於真正的問題。

如果要使用enable_if ,可以執行以下操作:

#include<type_traits>

enum class vals {
    Val1,
    Val2,
    Val3,
    Val4
};

template<vals v, std::enable_if_t<(v == vals::Val1 || v == vals::Val3)>* = nullptr>
class MyClass { };

int main() {
    MyClass<vals::Val1> ok;
    // MyClass<vals::Val2> ko;
}

另一個解決方案是使用static_assert

enum class vals {
    Val1,
    Val2,
    Val3,
    Val4
};

template<vals v>
class MyClass {
    static_assert((v == vals::Val1 || v == vals::Val3), "!");
};

int main() {
    MyClass<vals::Val1> ok;
    // MyClass<vals::Val2> ko;
}

等等,存在許多不需要constexpr功能的替代方案。

否則,讓函數成為@nm所提及的constexpr ,這就是全部。

謝謝你的回答。 我找到了另一種解決方案,可能對我的問題更好。 由於我必須為所有支持的值實現專門的方法,我甚至可以在非專用方法中設置斷言。

template<vals v>
MyClass<v>::method() {
  assert(check(v) && "Unsupported value!");
}

template<>
MyClass<Val1>::method() {
   // do it!
}

暫無
暫無

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

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