合并常量和非常量 std::list 的模板专用化
merging template specializations for const and non-const std::list
有没有一种简单的方法可以将两个模板专业化合并为一个,也许使用 std::enable_if
,用于以下 MWE?
#include <string>
#include <list>
#include <memory>
class A {
// ...
};
class B {
// ...
};
template<typename T> class C {};
template<typename T>
class C<std::list<T> &> : public A, public B
{
std::list<T> &l_ref;
public:
C(std::list<T> &lr) : l_ref{lr} { }
// ...
};
template<typename T>
class C<const std::list<T> &> : public A, public B
{
const std::list<T> &l_ref;
public:
C(const std::list<T> &lr) : l_ref{lr} { }
// ...
};
对于惯用语
template<typename T>
struct C<T, typename std::enable_if<
std::is_same<T, std::list<E> &>::value ||
std::is_same<T, const std::list<E> &>::value>::type>
: public A, public B
{
// ...
方式,我认为没有办法使E
可推论或指定"任何std::list
"的类型。
您可以先创建一个特征,然后使用 SFINAE,如下所示:
template <typename T> struct is_a_stdlist_ref : std::false_type {};
template <typename ... Ts>
struct is_a_stdlist_ref<std::list<Ts...>&> : std::true_type {};
template <typename ... Ts>
struct is_a_stdlist_ref<const std::list<Ts...>&> : std::true_type {};
template<typename T, typename Enabler = void> struct C;
template<typename T>
struct C<T, std::enable_if_t<is_a_stdlist_ref<T>::value>>
: public A, public B
{
//...
};
对于以下 MWE,有没有一种简单的方法可以将两个模板专业化合并为一个,也许使用 std::enable_if?
您是否接受没有std::enable_it
的解决方案?
为了使解决方案更加灵活,我建议定义一个类型特征,specIndex
,以修复一个类型依赖索引,其中0
是"泛型类型",1
是"std::list&or
const",其他整数可以引用其他专用化。
template <typename>
struct specIndex
{ static constexpr std::size_t value { 0U }; }; // generic version
template <typename T>
struct specIndex<std::list<T> &>
{ static constexpr std::size_t value { 1U }; }; // pro lists
template <typename T>
struct specIndex<std::list<T> const &>
{ static constexpr std::size_t value { 1U }; }; // pro lists
下一步是为C
添加默认模板整数参数
template <typename T, std::size_t = specIndex<T>::value>
class C
{ };
最后一步是定义索引 1(std::list<T> &
或常量(专用化
template<typename T>
class C<T, 1U> : public A, public B
{
private:
T & l_ref;
public:
C (T & lr) : l_ref{lr}
{ std::cout << "- list version" << std::endl; }
};
以下是完整示例
#include <string>
#include <list>
#include <memory>
#include <iostream>
class A
{ };
class B
{ };
template <typename>
struct specIndex
{ static constexpr std::size_t value { 0U }; }; // generic version
template <typename T>
struct specIndex<std::list<T> &>
{ static constexpr std::size_t value { 1U }; }; // pro lists
template <typename T>
struct specIndex<std::list<T> const &>
{ static constexpr std::size_t value { 1U }; }; // pro lists
template <typename T, std::size_t = specIndex<T>::value>
class C
{ };
template<typename T>
class C<T, 1U> : public A, public B
{
private:
T & l_ref;
public:
C (T & lr) : l_ref{lr}
{ std::cout << "- list version" << std::endl; }
};
int main ()
{
std::list<long> sll;
C<int> a;
C<std::list<long> &> b{sll};
C<std::list<long> const &> c{sll};
}
相关文章:
- .cpp和.h文件中的模板专用化声明
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 什么时候在C++中返回常量引用是个好主意
- 代理对象的常量正确性
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 具有常量引用参数的函数模板专用化
- 如何为静态常量模板化专用整数值分配存储
- 常量和非常量类型的相同模板专用化
- 常量字符*的模板方法专用化
- 如何将类成员专用于多个模板值(常量)?
- 合并常量和非常量 std::list 的模板专用化
- 专用常量成员函数的成员检测
- 视图和跨步视图以及常量噩梦的函数模板专用化
- 具有常量参考的可变参数模板专用化
- 常量和非常量 gsl::span 参数的函数模板专用化
- 类型上的模板专用化和常量限定符
- C++模板通过指针的函数/常量指针的函数进行的部分专用化没有什么不同
- 为什么专用模板函数不能同时接受类型及其常量版本?
- 常量和非常量模板专用化