Clang 拒绝这个演示,而 GCC 和 MSVC 接受它。(https://godbolt.org/z/M1Wsxs8fj)
谁是正确的?或者这是不正常的不需要诊断?
#include <type_traits>
#if 0
#define METHOD balabala // OK
#else
#define METHOD operator= // Clang error
#endif
struct base {};
template<typename T>
concept derived = std::is_base_of_v<base, T>;
template<derived Lhs, derived Rhs> struct assign;
template<typename T>
struct crtp: base {
template<derived Rhs>
constexpr auto METHOD(const Rhs& rhs) -> assign<T, Rhs> {
return {};
}
};
template<typename T>
struct foo: crtp<foo<T>> {
using crtp<foo<T>>::METHOD;
};
template<derived Lhs, derived Rhs>
struct assign: crtp<assign<Lhs, Rhs>> …Run Code Online (Sandbox Code Playgroud) 有没有办法(编译器扩展是可接受的)包含 C 标头并将包含的 C 函数标记为noexcept,但不修改标头?
例如,我有一个 C 库及其头文件header.h。不会将任何 C++ 回调传递给它,因此它永远不会抛出异常。我可以将包含的 C 函数标记为noexcept或告诉编译器它们永远不会抛出异常,以便编译器不必生成未使用的代码并为调用者启用一些可能的优化吗?请注意,使用 C 库的 C++ 代码应该仍然能够使用异常(因此不能选择禁用整个程序的异常)。
extern "C" {
#include "header.h" // Is there a way to mark included C functions here as noexcept?
}
Run Code Online (Sandbox Code Playgroud) 想象一下编写一些通用代码:
template<class...Args>
auto do_something(Args&&...args)
noexcept(noexcept(detail::do_something(std::forward<Args>(args)...)))
-> decltype(detail::do_something(std::forward<Args>(args)...))
{
return detail::do_something(std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
我不得不重复detail::do_something(std::forward<Args>(args)...)三遍这个长表情。
noexcept需要说明符来传播noexcept-ness。
需要尾随返回类型,因为许多标准类型特征和概念(例如invocable-families)需要知道直接上下文中的返回类型。
我知道这可以通过宏来解决。但是有没有任何 C++ 方法可以简化它,或者任何现有的工作可能有助于将来简化它?
例如,2015年写的一个答案提到了一项提案,该提案引入了noexcept(auto)但仍处于“我们认为 noexcept(auto) 的有效和合理使用是否足够重要以至于我们应该标准化它?”的状态。。
C++17 介绍template <class Fn, class...ArgTypes> struct is_invocable:
确定是否
Fn可以使用参数调用ArgTypes...。正式地,确定INVOKE(declval<Fn>(), declval<ArgTypes>()...)当被视为未计算的操作数时是否格式良好,其中INVOKE定义的操作在Callable.
但是,此模板不适用于模板化的 operator(),其(直接或间接)返回类型是自动推导的:
#include <type_traits>
#include <iostream>
struct A {
int a() { return 1; }
};
struct B {};
struct {
template<typename T>
auto operator()(T t) { return t.a(); }
} f1;
struct {
template<typename T>
auto operator()(T t) -> decltype(t.a()) { return t.a(); }
} f2;
struct {
template<typename T>
auto operator()(T t) -> decltype(f1(t)) { …Run Code Online (Sandbox Code Playgroud)