我可以在模板专业化中获取专业化值的名称/引用吗?
Can I get name / reference to specialization value inside template specialization?
我的代码:
enum class list{one, two};
template <list T> class Base;
template <> class Base <list::one>{
A a{list::one};
B b{list::one};
C c{list::one};
};
template <> class Base <list::two>{
B b{list::two};
C c{list::two};
D d{list::two};
};
但我想避免重复代码,并使用对专业化值的引用,如下所示:
template <> class Base <list::one>{
A a{T};
B b{T};
C c{T};
};
template <> class Base <list::two>{
B b{T};
C c{T};
D d{T};
};
我可以让污泥成为临时变量,但看起来也不太好:
template <> class Base <list::one>{
list T = list::one;
A a{T};
B b{T};
C c{T};
};
有什么方法可以获取模板特化值的引用吗?
在下面的示例中,我使用 SFINAE 使 T
在 Base
的定义中可用。具体来说,我做了以下事情:
- 向主模板添加了一个虚拟类型参数,
- 通过 not 指定参数
T
(并指定第二个虚拟类型参数) 使两个特化部分化
- 指定了第二个虚拟类型参数,通过
std::enable_if_t
. 强制 T
等于两个特化中的 list::one
和 list::two
#include <iostream>
#include <type_traits>
enum class list{one, two};
// to make the code compile
class A { public: A(list) {} };
class B { public: B(list) {} };
class C { public: C(list) {} };
class D { public: D(list) {} };
// primary template (second param's sole purpose is to allow partial spec.)
template <list T, typename = void>
class Base;
// partial specialization #1
template <list T>
class Base <T, std::enable_if_t<T == list::one>>{
A a{T};
B b{T};
C c{T};
public:
Base() { std::cout << "list::one\n"; }
};
// partial specialization #2
template <list T>
class Base <T, std::enable_if_t<T == list::two>>{
B b{T};
C c{T};
D d{T};
public:
Base() { std::cout << "list::two\n"; }
};
int main() {
Base<list::one> o;
Base<list::two> t;
}
这是通过 std::enable_if
使用 SFINAE 的一种非常标准的方式。类似的例子可以在 cppreference page on std::enable_if
上找到,其中最后一个例子(第一个评论 // primary template
的例子)重试了上面的代码。
我的代码:
enum class list{one, two};
template <list T> class Base;
template <> class Base <list::one>{
A a{list::one};
B b{list::one};
C c{list::one};
};
template <> class Base <list::two>{
B b{list::two};
C c{list::two};
D d{list::two};
};
但我想避免重复代码,并使用对专业化值的引用,如下所示:
template <> class Base <list::one>{
A a{T};
B b{T};
C c{T};
};
template <> class Base <list::two>{
B b{T};
C c{T};
D d{T};
};
我可以让污泥成为临时变量,但看起来也不太好:
template <> class Base <list::one>{
list T = list::one;
A a{T};
B b{T};
C c{T};
};
有什么方法可以获取模板特化值的引用吗?
在下面的示例中,我使用 SFINAE 使 T
在 Base
的定义中可用。具体来说,我做了以下事情:
- 向主模板添加了一个虚拟类型参数,
- 通过 not 指定参数
T
(并指定第二个虚拟类型参数) 使两个特化部分化
- 指定了第二个虚拟类型参数,通过
std::enable_if_t
. 强制
T
等于两个特化中的 list::one
和 list::two
#include <iostream>
#include <type_traits>
enum class list{one, two};
// to make the code compile
class A { public: A(list) {} };
class B { public: B(list) {} };
class C { public: C(list) {} };
class D { public: D(list) {} };
// primary template (second param's sole purpose is to allow partial spec.)
template <list T, typename = void>
class Base;
// partial specialization #1
template <list T>
class Base <T, std::enable_if_t<T == list::one>>{
A a{T};
B b{T};
C c{T};
public:
Base() { std::cout << "list::one\n"; }
};
// partial specialization #2
template <list T>
class Base <T, std::enable_if_t<T == list::two>>{
B b{T};
C c{T};
D d{T};
public:
Base() { std::cout << "list::two\n"; }
};
int main() {
Base<list::one> o;
Base<list::two> t;
}
这是通过 std::enable_if
使用 SFINAE 的一种非常标准的方式。类似的例子可以在 cppreference page on std::enable_if
上找到,其中最后一个例子(第一个评论 // primary template
的例子)重试了上面的代码。