【问题标题】:Rename std::vector to another class for overloading?将 std::vector 重命名为另一个类以进行重载?
【发布时间】:2014-01-07 13:59:31
【问题描述】:

看看这段代码。

#include <vector>

template<class ...Args>
using other_vector = std::vector<Args...>;

template<class T>
void f(std::vector<T>& ) {}
template<class T>
void f(other_vector<T>& ) {}

int main()
{
    other_vector<int> b;
    f(b);
    return 0;
}

它无法编译,因为 f 正在被重新声明。我完全理解这个错误。但是,我需要第二个类,其行为类似于 std::vector&lt;T&gt;,但将被视为不同的类型,因此如上例中的重载是合法的。

我能做什么?

  • 让新类以std::vector&lt;T&gt; 作为基类。这可能有效,但不应从 std 容器继承。
  • 让新类有一个 std::vector 类型的成员,然后重新声明所有函数以重定向到该成员的函数。听起来工作量很大。

还有更好的选择吗?允许使用 C++11 或 C++14。

【问题讨论】:

  • 看看BOOST_STRONG_TYPEDEF。如果它不适用于模板,您可能会汲取灵感来制作一些可以使用的东西。
  • 你确定你需要两个几乎相同类型的函数吗?
  • 你能说出你为什么需要它吗?为什么不使用struct vector_wrapper{ std::vector&lt;T&gt; vector; };
  • @StoryTeller 是的,为什么不呢?
  • 只要您知道不该做什么,从标准容器继承是可以的(尽管不常用)。缺少虚拟析构函数会造成伤害,但前提是您允许/要求其行为。

标签: c++ c++11 stdvector


【解决方案1】:

你可能会尝试弄乱分配器:

template<class T>
struct allocator_wrapper : T { using T::T; };

template<class T, class A = std::allocator<T>>
using other_vector = std::vector<T, allocator_wrapper<A>>;

Live example

【讨论】:

  • using T::T; Whoa O.O +1
  • @Johannes 如果您需要更多这些不同的类型,只需在 allocator_wrapper 中添加一个整数参数,您就可以拥有任意数量的它们...... :)
  • @DanielFrey 绝妙的主意,+1 为您的评论和您的回答
  • 为什么不简单:template> struct other_vector : std::vector { using std::vector::向量; }; ?
  • @kiba 你有时需要类本身是一个std::vector 而不仅仅是派生自它的东西,here's an example 这表明差异是可以检测到的,可能没有多少用例可以你会这样做,但它们确实存在。
【解决方案2】:

如果您需要多个副本,可以将其设为模板并为“克隆号”取一个int 模板参数

【讨论】:

  • 但是我仍然需要使用我上面提到的两点之一,还有提到的缺点?
  • @Johannes true,但您可以将int 模板参数与您对 1 个克隆的任何解决方案结合起来,将其扩展到 N
【解决方案3】:

您可以按如下方式包装您的类型:

// N allow to have several 'version' of the same type T
template <typename T, int N = 0>
class WrapperType
{
public:
    WrapperType() = default;
    WrapperType(const WrapperType&) = default;
    WrapperType(WrapperType&&) = default;

    template <typename ... Ts>
    explicit WrapperType(Ts&& ... ts) : t(std::forward<Ts>(ts)...) {}

    // implicit conversion
    // you may prefer make them explicit or use name get().
    operator const T& () const { return t; }
    operator T& () { return t; }

private:
    T t;
};

所以对于你的情况:

template<class T>
using other_vector = WrapperType<std::vector<T>>;

【讨论】:

    猜你喜欢
    • 2022-01-10
    • 2011-12-15
    • 2019-06-09
    • 1970-01-01
    • 2020-09-07
    • 2019-11-07
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    相关资源
    最近更新 更多