如何编写从 Foo<T> 到 Foo<T const> 的转换?

问题描述 投票:0回答:1

我正在为具有克隆功能的类编写一个继承自

std::unique_ptr
的类:

template <typename T>
class cl_ptr : public std::unique_ptr<T>
{
    public:
        cl_ptr() noexcept = default;
        cl_ptr(T* p) noexcept : std::unique_ptr<T>(p) {}
        cl_ptr(cl_ptr<T> const& cp) : std::unique_ptr<T>(cp ? cp->clone() : nullptr) {}
        cl_ptr(cl_ptr<T>&&) noexcept = default;
        cl_ptr<T>& operator=(cl_ptr<T> const& cp) { this->reset(cp ? cp->clone() : nullptr); return *this; }
        cl_ptr<T>& operator=(cl_ptr<T>&& cp) noexcept = default;
        ~cl_ptr() noexcept = default;
};

当我尝试从类型为

T
的实例转换为类型为
T const
的实例时出现错误:

cl_ptr<Foo> p1(new Foo);
cl_ptr<Foo const> p2 = p1; // <- Compiler error here
// error: conversion from ‘cl_ptr<Foo>’ to non-scalar type ‘cl_ptr<const Foo>’ requested

但是我不知道如何实现它

当然我不希望这段代码编译:

cl_ptr<Foo const> p1(new Foo);
cl_ptr<Foo> p2 = p1; // <- Always wrong

最小可重现示例:

# include <memory>

template <typename T>
class cl_ptr : public std::unique_ptr<T>
{
    public:
        cl_ptr() noexcept = default;
        cl_ptr(T* p) noexcept : std::unique_ptr<T>(p) {}
        cl_ptr(cl_ptr<T> const& cp) : std::unique_ptr<T>(cp ? cp->clone() : nullptr) {}
        cl_ptr(cl_ptr<T>&&) noexcept = default;
        cl_ptr<T>& operator=(cl_ptr<T> const& cp) { this->reset(cp ? cp->clone() : nullptr); return *this; }
        cl_ptr<T>& operator=(cl_ptr<T>&& cp) noexcept = default;
        ~cl_ptr() noexcept = default;
};

class Foo
{
    public:
        Foo() = default;
        Foo(Foo const&) = default;
        ~Foo() noexcept = default;
        Foo* clone() const { return new Foo(*this); }
};

int main()
{
    cl_ptr<Foo> p1(new Foo);
    cl_ptr<Foo const> p2 = p1;
    cl_ptr<Foo> p3 = p2; // must fail

    return 0;
}
c++ templates c++17 implicit-conversion
1个回答
0
投票

一般来说:你不能。由于模板专业化,

A<B const>
A<B>
可能是完全不同的东西。因此,一般来说,具有不同模板参数列表的类模板实例被视为不同的、不相关的类型。

对于智能指针,标准库竭尽全力在某些情况下启用此类转换,但这些都是相应类模板的自定义实现。

可以为您的特定班级做同样的事情。但是 cl_ptr

 似乎是 
std::unique_ptr
 的一个简单包装,所以为什么不直接使用 
std::unique_ptr
 呢?

© www.soinside.com 2019 - 2024. All rights reserved.