【问题标题】:typecasting object of one template type to another template type in c++将一种模板类型的对象类型转换为c ++中的另一种模板类型
【发布时间】:2018-10-07 12:25:28
【问题描述】:

我使用模板在 C++ 中创建了一个堆栈类。程序首先询问要在堆栈中输入的数据类型,例如。 int、float、char 等 我怀疑我是否创建了两个对象,例如,

Stack<int> obj_integer(size);
Stack<char> obj_character(size);

其中 Stack 是使用模板的用户定义类,而 size 是用户传递的堆栈的大小。然后我将如何将对象“obj_integer”类型转换为对象“obj_character”。那就是我希望 obj_integer 现在采用 char 类型数据而不是整数类型。

【问题讨论】:

  • 你不能。 C++ 不能以这种方式工作。您必须从头开始创建一个新对象,并对其进行适当的初始化。 C++ 不会为您做任何事情,您必须自己做。当然,如果你编写了适当的模板构造函数或赋值运算符,你当然可以说“obj_integer=obj_character”并让它像那样工作,但你必须自己编写实现它的赋值运算符。 C++ 不会为你做这件事。

标签: c++ class templates


【解决方案1】:

假设您的 Stack 看起来与此类似;

template<typename Type>
class Stack
{
public:
    template<typename T>
    Stack(T t){}
};

你可以静态转换为;

Stack<int> obj_integer(1);
Stack<char> obj_character('a');
obj_integer = static_cast<Stack<char>>(obj_character);

这是你不应该做的一件事。想象一下如果stack 有一些成员不能被静态转换处理会发生什么。你最终会得到没有正确处理的转换。

因此,更好的选择是重载赋值运算符和复制构造函数,以确保所有内容都正确转换。

template<typename Type>
class Stack
{
public:

    // template < typename T>
    template < typename T>
    Stack( const Stack< T > & obj ) //copy conustructor
    {
        // do conversion
    }

    template < typename T >
    Stack& operator=( const Stack< T > & obj ) //overloading assignment operator
    {
        // do conversion
        return *this;
    }

    template<typename T>
    Stack(T t){}

};


int main()
{

    Stack<int> obj_integer(1);
    Stack<char> obj_character('a');
    Stack<char> obj_character2('b');
    Stack<int> obj_integer2 = obj_character;  //copies the obj_character to  obj_integer2 using copy constructor
    obj_integer2 = obj_character2;            //assigns the obj_character2 to  obj_integer2 using assignment operator
    return 0;
}

【讨论】:

    【解决方案2】:

    可以使用C++17的std::anystd::variant,或者定义自己的对象类型:

    Stack<std::variant<int, double, char>> obj_stack(size);
    

    如果Stack 有一个类似于std::vector 的接口,那么使用如下:

    obj_stack.push_back(12);
    std::cout << std::get<int>(obj_stack.back()) << '\n';
    obj_stack.push_back('x');
    std::cout << std::get<char>(obj_stack.back()) << '\n';
    

    另外,查找std::holds_alternativestd::get_ifstd::visit。它们可以帮助您检测您的元素是什么类型,并采取相应的行动。


    如果不能使用 C++17,那么可以使用boost::variant

    如果 boost 和 C++17 都不是一个选项,您总是可以定义自己的类层次结构来保存不同的类型。但在这种情况下,您很可能会重新发明 std::anystd::variant,这不是一个好主意(除非您的目标是了解如何实现这些东西)。

    【讨论】:

    • 是否引入了 std:: 变体来避免强制转换?这似乎有点矫枉过正。
    • @Yucel_K std::variant 类可以安全地将不同类型插入一个堆栈。根据问题,只有一个堆栈,其中每个条目都可以是不同的类型。这正是 std::variant 的用途。维护单独的堆栈并同步它们以使它们看起来像一个堆栈,容易出错且效率低下。
    • hmm.. 也许问题需要更多澄清,比如他为什么需要演员。据我了解,他只想将一种堆栈类型转换为另一种。
    • @Yucel_K 我同意他们想将一种堆栈类型转换为另一种。对我来说,这似乎是一个 xy 问题。需要强制转换的真正原因似乎是能够处理堆栈内的不同对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    • 2012-03-28
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 2023-02-07
    相关资源
    最近更新 更多