我試圖了解如何使用帶有 std::enable_if 的型別特征來“啟用”類的部分特化。這是我試圖開始作業的示例代碼
#include <type_traits>
#include <iostream>
class AbstractFoo {
public:
virtual const char* name() const = 0;
};
template <typename T, typename Enable = void>
class Foo;
template <>
class Foo<int> : public AbstractFoo{
public:
const char* name() const override { return "int"; }
};
template <>
class Foo<char> : public AbstractFoo {
public:
const char* name() const override { return "char"; }
};
template <typename T>
class Foo<T, typename std::enable_if<std::is_enum<T>::value, T>::type> : public AbstractFoo {
public:
const char* name() const override { return "enum"; }
};
enum class MyEnum {
VAL1,
VAL2,
VAL3
};
int main() {
Foo<int> v1;
Foo<char> v2;
Foo<MyEnum> v3;
std::cout << "v1.name()=" << v1.name() << std::endl;
std::cout << "v2.name()=" << v2.name() << std::endl;
std::cout << "v3.name()=" << v3.name() << std::endl;
return 0;
};
我的目標是為某些型別(例如 int 和 char)提供特定的特化,但是,如果型別是列舉,則使用我的部分特化。但是,當我嘗試編譯此代碼時,出現以下錯誤
錯誤:聚合“Foo v3”的型別不完整,無法定義
我認為這意味著我的專業沒有被選擇,因此永遠不會被定義。我究竟做錯了什么?
uj5u.com熱心網友回復:
在第二個模板引數的宣告中Foo默認為void. 這意味著以下變數:
Foo<MyEnum> v3;
實際上是
Foo<MyEnum, void> v3;
現在的問題是:這是否符合您想要的專業化?不是真的,因為在您的列舉專業中:
std::is_enum<T>::value = true什么時候T = MyEnumstd::enable_if<std::is_enum<T>::value, T>::type = T = MyEnum什么時候T=MyEnum
因此,對于T=MyEnum,您給出的特化 forFoo<T, T>與上面的變數不匹配。
如評論中所述,一個簡單的解決方法是將專業化宣告為
class Foo<T, typename std::enable_if<std::is_enum<T>::value>::type>
這樣,第二個模板引數是voidwhen T=MyEnum,所以它匹配 的變數宣告v3。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/433962.html
上一篇:使用模板在C 中復制建構式的問題
下一篇:輸入具有特定成員函式的多載函式
