是否在std::Function返回类型定义中使用[[nodisard]]?
我想知道有没有这样的方法:
using CallbackType = std::function<[[nodiscard]]bool(void)>;
(我知道上面的代码无法编译,并抱怨nodiscard
无法应用于类型!)
我的目标是强制回调的调用方检查它的返回值!
解决方案
您可以直接包装std::function
或真正的lambda来修改属性,如[[nodiscard]]
。
您关于公共继承有问题的评论是完全正确的。但是,这不适用于私有继承,因为您可以控制这些问题。
编辑:但如果您绝对不喜欢它,您可以重写下面的代码,以使用私有成员而不是私有继承,代价是使代码更冗长,但好处是支持原始函数指针。
template <typename Function>
struct NoDiscard : private Function {
NoDiscard() = default;
NoDiscard(NoDiscard const&) = default;
NoDiscard(NoDiscard&&) = default;
NoDiscard& operator=(NoDiscard const&) = default;
NoDiscard& operator=(NoDiscard&&) = default;
NoDiscard(Function&& fn) : Function(std::move(fn)) {}
NoDiscard(Function const& fn) : Function(fn) {}
template <typename... Ts>
[[nodiscard]] auto operator()(Ts&&... ts) {
return Function::operator()(std::forward<Ts>(ts)...);
}
};
// convenience function to make the call look intuitive
template <typename Function>
auto add_nodiscard(Function&& f) {
return NoDiscard<Function>(std::forward<Function>(f));
}
这将允许您简单地add_nodiscard
到任何函数器或可调用类型。示例:
void test_good(auto fn) {
(void)fn();
}
void test_bad(auto fn) {
fn();
}
int main() {
test_good( ( ([](){return true;})));
test_bad ( ( ([](){return true;})));
test_good(add_nodiscard( ([](){return true;})));
test_bad (add_nodiscard( ([](){return true;}))); // warns about discarded result
test_good( (std::function<bool(void)>([](){return true;})));
test_bad ( (std::function<bool(void)>([](){return true;})));
test_good(add_nodiscard(std::function<bool(void)>([](){return true;})));
test_bad (add_nodiscard(std::function<bool(void)>([](){return true;}))); // warns about discarded result
}
live demo
这有一个警告,不能将其与必须接收std::function
对象的类型一起使用。
我认为这样的目标是不可能的,因为您不能更改库函数的类型或直接向其添加属性。并且您在std::function
调用之前添加的任何包装都不会对[[nodiscard]]
产生影响,因为std::function
将尽职尽责地从其被调用者返回返回值。
免责声明:我是说,这是绝对不可能的,唯一的目的是被证明是错误的。
相关文章