- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有一个包含多个函数对象的库,这些函数对象可能只接受几种类型,具体取决于 std::is_integral
.我要std::is_invocable
在条件失败时返回 false
,但当用户尝试调用函数对象的实例时,我还想要一个不错的 static_assert
错误消息。这是我目前拥有的函数对象的一个简化示例:
struct function
{
template<typename Iterator>
auto operator()(Iterator first, Iterator last) const
-> std::enable_if_t<std::is_integral_v<
typename std::iterator_traits<Iterator>::value_type
>>
{ /* something */ }
};
通过这样的实现,std::is_invocable
是 std::false_type
当不满足 SFINAE 条件时,如预期的那样,但用户在他们遇到难看的 SFINAE 错误消息时尝试使用不满足 SFINAE 条件的参数调用函数对象。
为了获得更好的错误消息,我尝试了以下解决方案:
struct function
{
template<typename Iterator>
auto operator()(Iterator first, Iterator last) const
-> void
{
static_assert(std::is_integral_v<typename std::iterator_traits<Iterator>::value_type>,
"function can only be called with a collection of integers");
/* something */
}
};
通过此实现,当不满足原始 SFINAE 条件时,用户会收到友好的错误消息,但 std::is_invocable
是 std::true_type
当被问及是否 function
实例可以处理不满足 std::is_integral
的类型。
我尝试了一些涉及 decltype(auto)
、if constexpr
和其他机制的技巧和变体,但无法获得错误消息很好且 的类code>std::is_invocable
在询问是否可以使用不正确的类型调用 function
时对应于预期的 std::false_type
。
我在这里错过了什么?有没有办法同时获得正确的 std::is_invocable
和 用户友好的错误消息?
最佳答案
这是一个糟糕的方法。添加重载:
template <typename Iterator>
auto operator()(Iterator first, Iterator last) const
-> std::enable_if_t<std::is_integral_v<
typename std::iterator_traits<Iterator>::value_type
>>;
template <typename Iterator, class... Args>
void operator()(Iterator, Iterator, Args&&... ) const = delete; // must be integral
这满足 is_invocable<>
条件,因为受限函数模板更专业和更受欢迎 - 所以如果满足条件,则函数是可调用的,否则将被删除。
这在错误情况下做得更好一些,因为如果你尝试调用它,你会得到:
foo.cxx: In function ‘int main()’:
foo.cxx:31:13: error: use of deleted function ‘void function::operator()(Iterator, Iterator, Args&& ...) const [with Iterator = std::__cxx11::basic_string<char>*; Args = {}]’
f(&i, &i);
^
foo.cxx:19:10: note: declared here
void operator()(Iterator, Iterator, Args&&... ) const = delete; // must be integral
^~~~~~~~
注释显示在错误消息中,有点像静态断言消息?
这实际上是Concepts的动机之一。用requires
而不是 enable_if
,我们得到:
foo.cxx: In function ‘int main()’:
foo.cxx:26:13: error: no match for call to ‘(function) (std::__cxx11::string*, std::__cxx11::string*)’
f(&i, &i);
^
foo.cxx:11:10: note: candidate: void function::operator()(Iterator, Iterator) const requires is_integral_v<typename std::iterator_traits<_Iter>::value_type> [with Iterator = std::__cxx11::basic_string<char>*]
void operator()(Iterator first, Iterator last) const
^~~~~~~~
foo.cxx:11:10: note: constraints not satisfied
foo.cxx:11:10: note: ‘is_integral_v<typename std::iterator_traits<_Iter>::value_type>’ evaluated to false
那是……我想好一点。
关于c++ - 充分利用 static_assert 和 std::is_invocable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44978803/
我正在尝试创建一个由 std::initializer_list 初始化的示例数组类。我想在编译时检查初始化列表的大小是否不超过数组的大小。由于静态断言只能评估 constexpr,因此不会编译此代码
这是另一个 question 的后续内容 我试图在编译时确定特定实现是否在结构中添加了未命名的填充。像 gcc 这样的特定实现允许使用编译指示来控制结构中的填充和对齐,但代价是与其他实现兼容。由于 C
因此,我正在寻找一种方法,如果用于声明对象的值等于另一个值(不希望使用 C 的 assert 宏),则会导致编译时错误. 是的,我知道为什么会出现这个问题......编译器在他/她提示expressi
是否可以对数组值进行编译时检查? 例子: typedef enum { dummy0 = 0, dummy1, dummy2 } eDummyEnum; typedef str
我的问题是,下面的代码是否有效: template class Class { static_assert(sizeof(i) == 0, "Class instantiated with i
我正在尝试检查参数包中的每个参数是否可以存储在 8 个字节以内(sizeof inline auto invoke(std::uint64_t hash, Arguments... argument
我试图禁止对我已有的类的引用,但我看到了一些奇怪的行为。我已经构建了一个玩具示例来展示正在发生的事情。如果我有这个: template struct something { }; template
我有这样的情况: #define FOO(Readonly) static_assert(Readonly, "Fire!"); Readonly 显然会按字面意思粘贴为“false”或“true”,
我有一个函数模板,它接受一个输出迭代器参数。我如何使用 static_assert 检查实例化是否使用了适当的迭代器? (即,它既是一个输出迭代器,又分配正确类型的元素。) #include #in
在 C++11 中是否有一种优雅的方式来执行条件 static_assert 例如: template class MyClass { COMPILE_TIME_IF( IsTypeBuil
有(不要担心这段代码的长度,专注于struct X和Range)(你可以复制和粘贴并且应该编译): 已编辑 #include #include //This is from file "S
我在编译时过滤一个元组,如果元组为空或者元组包含多个元素,我想输出一条自定义错误消息。 static_assert 似乎有点太复杂了,因为我需要使用 bool 逻辑。 static_assert(si
现代优化 C++ 编译器是否受益于 static_asserts? 例如,如果我断言一个整数只能在一个受限范围内,编译器是通过优化步骤携带该信息还是它仍然只是一个整数? 请不要回答编译器可以考虑它。问
我想做一些static dispatch的工作,让基类static_cast this指针指向派生类并调用同名函数来实现多态。我还想用 static_assert 来确保派生类确实重载了特定功能(否则
我有一个模板函数来操作递归数据结构。在调用的初始函数中,我有以下形式: template auto get(param i) -> int { static_assert(Pos (i.re
我有一个函数模板定义如下: template Test &operator Test &operator::value || std::is_same::valu
我有这段代码来确定模板类型是否有 foo(): template struct has_foo : std::false_type {}; template struct has_foo().fo
我想使用 static_assert 对我的类的配置实现各种限制。早些时候,我只使用一个枚举,并且只允许一个需要所述枚举的构造函数来对我的类实现限制。如果我有类似下面的内容并且范围是从 0 到 4,这
为什么 std 库不使用这些呢?目前,如果对不可复制对象的复制构造函数进行调用,则错误消息可能有点“神秘”或让以前从未遇到过的人感到困惑。 我第一次收到此错误消息时,我不知道问题出在哪里(我从未想过不
为什么主体中的这个 static_assert 比我正在检查的错误早于代码中发生的错误?这是标准行为还是特定于编译器? 我很惊讶地发现这是我想要实现的: template Fizzer_t::Fizz
我是一名优秀的程序员,十分优秀!