gpt4 book ai didi

c++ - 使用 static_assert() 提供更好的编译时错误(比编译器)

转载 作者:行者123 更新时间:2023-11-30 00:53:33 25 4
gpt4 key购买 nike

昨天,我花了很长时间才开始处理编译时错误,该错误是由从非 const 对象调用 const 成员函数引起的,如下例所示:

// my utility header
template<typename derived>
struct crtp_task : task
{
std::list<task*> list;

// note: cannot be const, as task::allocate_child() isn't
template<typename... Args>
void add_child(Args&&... args)
{
list.push_back(new(task::allocate_child())
derived(std::forward<Args>(args)...));
}
/* ... */
};

// an application
struct my_task : crtp_task<my_task>
{
some_data data;
/* ... */
my_task(some_data d) data(d) {}
void generate_children() const // constant member
{
/* ... */
some_data child_data = /* ... */;
this->add_child(child_data); // error: cannot call non-const member
}
};

clang 错误消息有好几行而且太隐晦(没有提到 const),但 gcc 提出了一个更好的错误(虽然行数更多,但最终提示我忽略了 cv 限定符)。

因此,为了避免将来发生此类事情,我考虑在实用程序 header 中使用 static_assert()。我天真的做法

// my utility header
template<typename derived>
struct crtp_task : task
{
std::list<task*> list;

// note: cannot be const, as task::allocate_child() isn't
template<typename... Args>
void add_child(Args&&... args)
{
list.push_back(new(task::allocate_child())
derived(std::forward<Args>(args)...));
}

// note: catch call from const objects
template<typename... Args>
void add_child(Args&&...) const
{
static_assert(false,"add_child() const called");
}
/* ... */
};

失败,因为编译器会立即触发错误,即使从未调用模板 void add_child() const。我还能怎么做?

最佳答案

如果您希望某些重载在重载决策中被选中时导致编译错误,您可以使用新的 = delete 功能。

template<typename... Args>
void add_child(Args&&...) const = delete;

这将生成一个很好的简单错误,类似于“使用已删除的函数 void add_child(Args&&...) const”。

关于c++ - 使用 static_assert() 提供更好的编译时错误(比编译器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16101169/

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