gpt4 book ai didi

c++ - 如何基于作为 STL 容器的模板参数模拟选定成员函数的部分特化?

转载 作者:可可西里 更新时间:2023-11-01 18:26:21 24 4
gpt4 key购买 nike

我正在使用一个使用 STL 容器作为模板参数的类。不过,并非所有容器都提供相同的方法,因此我试图找出如何根据所使用的容器专门化特定方法。

例子:

template<typename container>
class A
{
private:
container m_container;
public:
void foo(); // does something container specific

// more generic methods that work with any container
};

下面的代码不会编译说“无法匹配方法特化”,但这大约是我想要实现的:

template<typename T>
template<>
void A<std::vector<T> >::foo()
{
// vector specific implementation
}

template<typename T>
template<>
void A<std::map<T> >::foo()
{
// map specific implementation
}

我必须支持许多编译器,包括 MSVC2010、gcc C++99、旧的 Solaris 编译器...

我发现解决这个问题的唯一方法是实现执行 foo 应该执行的任何操作的外部方法,并为不同的容器类型重载它们。但我不想在全局范围内公开这些功能,有没有办法通过专门化来实现?

无法外包它们的特殊情况是构造函数特化......

最佳答案

选项 #1

使用标签分派(dispatch):

template <typename T>
struct tag {};

template <typename container>
class A
{
private:
container m_container;

template <typename T, typename Alloc>
void foo_spec(tag<std::vector<T, Alloc> >)
{
// vector specific implementation
}

template <typename K, typename V, typename C, typename Alloc>
void foo_spec(tag<std::map<K,V,C,Alloc> >)
{
// map specific implementation
}

public:
void foo()
{
foo_spec(tag<container>());
}

// more generic methods that work with any container
};

DEMO 1

选项 #2

使用静态成员函数部分特化一个单独的类:

template <typename T>
struct Impl;

template <typename T, typename Alloc>
struct Impl<std::vector<T, Alloc> >
{
static void foo_spec()
{
// vector specific implementation
}
};

template <typename K, typename V, typename C, typename Alloc>
struct Impl<std::map<K,V,C,Alloc> >
{
static void foo_spec()
{
// map specific implementation
}
};

template <typename container>
class A
{
private:
container m_container;

public:
void foo()
{
Impl<container>::foo_spec();
}

// more generic methods that work with any container
};

DEMO 2

选项 #3

Derive from a partially specialized class + CRTP 习语:

template <typename container>
class A;

template <typename CRTP>
struct Base;

template <typename T, typename Alloc>
struct Base<A<std::vector<T, Alloc> > >
{
void foo()
{
// vector specific implementation
A<std::vector<T, Alloc> >* that = static_cast<A<std::vector<T, Alloc> >*>(this);
}
};

template <typename K, typename V, typename C, typename Alloc>
struct Base<A<std::map<K,V,C,Alloc> > >
{
void foo()
{
// map specific implementation
A<std::map<K,V,C,Alloc> >* that = static_cast<A<std::map<K,V,C,Alloc> >*>(this);
}
};

template <typename container>
class A : public Base<A<container> >
{
friend struct Base<A<container> >;

private:
container m_container;

public:
// more generic methods that work with any container
};

DEMO 3

选项 #4

使用 David Rodríguez - dribeas 建议的反向 继承层次结构在评论中:

template <typename container>
class Base
{
private:
container m_container;

public:
// more generic methods that work with any container
};

template <typename container>
class A;

template <typename T, typename Alloc>
class A<std::vector<T, Alloc> > : public Base<std::vector<T, Alloc> >
{
public:
void foo()
{
// vector specific implementation
}
};

template <typename K, typename V, typename C, typename Alloc>
class A<std::map<K,V,C,Alloc> > : public Base<std::map<K,V,C,Alloc> >
{
public:
void foo()
{
// map specific implementation
}
};

DEMO 4

关于c++ - 如何基于作为 STL 容器的模板参数模拟选定成员函数的部分特化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27444624/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com