如何处理插入到自定义容器中的无效数据类型

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

我有一个当前正在测试的自定义链接列表容器。我的测试之一是首先构建容器以接受 uint8_t 类型,然后尝试插入 float 类型并触发异常。问题是在我的附加函数中,附加了浮点数而没有触发我的异常块。当我打印数据时,存储浮点数的节点的实际内容不会显示,但链表的大小在追加后发生变化,所以看起来确实是数据被追加了。

如何检查类型以强制在这种特殊情况下抛出运行时错误?

这是我的附加函数代码和失败的测试。

...
template <typename T>
        void libdsa::libstructures::LinkedList<T>::append(T datum)
        {
            // Triggers even during a valid insertion.
            // if (typeid(datum) != typeid(this))
            // {
            //    throw std::runtime_error("Invalid type being inserted.");
            // }

            // Fill the head node if it's empty. Otherwise append a new node.
            if (_head == nullptr)
            {
                try
                {
                    _head = new libdsa::libstructures::Node<T>(datum);
                    _head->_next = _head;
                    _head->_prev = _head;
                }
                catch(const std::exception& e)
                {
                    std::cerr << e.what() << '\n';
                }
            }
            else
            {
                try
                {
                    libdsa::libstructures::Node<T> *current = _head;

                    // Create the new node
                    libdsa::libstructures::Node<T> *newNode = new libdsa::libstructures::Node<T>(datum);

                    // Go to the end of the list
                    while (current->_next != _head)
                    {
                        current = current->_next;
                    }

                    // Append the new node and set the directional pointers.
                    current->_next = newNode;
                    newNode->_prev = current;
                    newNode->_next = _head;
                }
                catch(const std::exception& e)
                {
                    std::cerr << e.what() << '\n';
                }
            }

            ++_size;
        }
...
TEST(LinkedList, testInvalidAppend)
{
    std::vector<uint8_t> data = {'C', 'O', 'D', 'E'};
    auto list = setup(data);

    float temp = 23.22;
    list.append(temp);

    list.print();
    ASSERT_EQ(data.size(), list.getSize());
}
libdsa::libstructures::LinkedList<uint8_t> setup(std::vector<uint8_t> &data)
{
    libdsa::libstructures::LinkedList<uint8_t> list;

    for (size_t i = 0; i < data.size(); ++i)
    {
        list.append(data[i]);
    }
    
    return list;
}

我希望在执行此无效操作时抛出异常(或运行时错误),但无论有或没有我的条件语句,目前都不会触发异常。

最初,我尝试使用 try-catch 块,认为编译器会为我捕获它并打印出异常。然而,它并没有触发它并分配数据块。我尝试的另一个选项是在运行时获取正在插入的数据和容器类型的 typeid,但这在成功的情况下导致插入失败(其中数据和容器的类型实际上是相同的) .

c++ data-structures linked-list
1个回答
0
投票

问题是

float
已经在运行时转换为
uint8_t
,因此如果没有编译时解决方案,您无法检查它。

如果您使用的是 C++17 或更高版本,则可以利用

constexpr if
:

template <typename T>
void libdsa::libstructures::LinkedList<T>::append(T datum)
{
    if constexpr (!std::is_same_v<T, uint8_t>)
    {
        std::cout << "This is an invalid type " << datum << "\n";
        return;  // or throw an exception
    }
    //...
}

如果类型不是

uint8_t
,则
if
块是
true
并且将执行代码。

这是一个实例


如果您想在发送错误类型时停止编译并且根本不生成可执行文件,您可以使用

static_assert
(适用于 C++11):

#include <cstdint>
//... 
template <typename T>
void libdsa::libstructures::LinkedList<T>::append(T datum)
{
    // This will stop the compilation if the wrong type is sent   
    static_assert(std::is_same_v<T, uint8_t>, "It is not a uint8_t");
    //...
}

这是一个实例

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