require子句中不允许哪些替换失败?

朗布拉克

如果所有模板参数都是唯一的,我试图编写一个返回true的函数。

伪代码:

template<typename... Ts>
auto types_are_unique() -> bool {
  return (no two Ts are the same);
}

我不是要“手动”相互比较T,而是要使用这样的事实:如果两个或多个基类相同,则不允许多重继承。

#include <utility>

template <typename T>
struct X {};

template <typename... Ts>
struct Test : X<Ts>... {};

template <typename... Ts>
constexpr auto types_are_unique() -> bool {
  return false;
}

template <typename... Ts>
requires requires { Test<Ts...>{}; }
constexpr auto types_are_unique() -> bool {
  return true;
}

int main() {
  static_assert(types_are_unique<int, float>()); // compiles
  static_assert(not types_are_unique<int, int>()); // fails
}

gcc和clang都同意这不能编译,因为unique.cpp:7:8: error: duplicate base type ‘X<int>’ invalid

阅读https://en.cppreference.com/w/cpp/language/constraints#Requires_expressions,这真是令人惊讶

将模板参数替换为模板实体的声明中使用的require-表达式可能会导致其要求中形成无效的类型或表达式,或者违反这些要求的语义约束。在这种情况下,required表达式的计算结果为false,不会导致程序格式错误。

clang和gcc错误吗?还是cppreference错误?或者(很可能)我读错了吗?

requires表达式中不允许出现哪类替换失败请参阅C ++ 20当前草案的相应部分。

巴里

在require表达式中不允许发生哪类替换失败?

与其他任何地方一样。这实际上并不是特定于概念的。这是您的示例的稍作修改的版本,它演示了C ++ 11的相同问题:

using size_t = decltype(sizeof(0));

template <typename T>
struct X {};

template <typename... Ts>
struct Test : X<Ts>... {};

template <typename...> struct typelist { };

template <typename... T, size_t = sizeof(Test<T...>)>
constexpr auto types_are_unique(typelist<T...>) -> bool {
    return true;
}
constexpr auto types_are_unique(...) -> bool {
    return false;
}

// ok
static_assert(types_are_unique(typelist<int, float>()));

// compile error
static_assert(not types_are_unique(typelist<int, int>()));

该问题与替代直接上下文中的实质有关。这是[temp.deduct] / 8中引入的一个术语,但并未真正明确定义

如果替换导致无效的类型或表达式,则类型推导失败。如果使用替换的参数编写,则无效的类型或表达式是格式错误的,需要进行诊断。[注意:如果不需要诊断,则程序仍然格式错误。访问检查是替代过程的一部分。—尾注]只有在函数类型,其模板参数类型及其显式说明符的直接上下文中的无效类型和表达式才可能导致推论失败。[注:替换为类型和表达式可能会导致诸如实例化类模板专业化和/或函数模板专业化,生成隐式定义的函数等效果。此类效果不在“立即上下文”中,并且可以导致程序格式错误。—尾注]

通常的想法是,仅声明中的失败会导致替换失败,而定义中的失败会导致硬错误,这些错误会导致程序格式错误。在这里的示例中,问题不在于Test<int, int>它的定义中的声明(在我们到达其基类的时候)。这被认为为时已晚-即时上下文之外的失败不再是替代失败。


我们甚至有一个核心问题(1844),要求更好的定义。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

PostgreSQL错误中WHERE子句中不允许的聚合

来自分类Dev

GROUP BY子句中不允许使用SQL Server XML方法

来自分类Dev

GROUP BY子句中不允许使用SQL Server XML方法

来自分类Dev

vb表适配器在IN子句中不允许多个参数

来自分类Dev

GROUP BY 子句中不允许使用聚合函数(代码 1)

来自分类Dev

zramswapon失败:不允许操作

来自分类Dev

sudo chown失败,不允许操作

来自分类Dev

modprobe失败,显示“不允许操作”

来自分类Dev

zramswap 失败:不允许操作

来自分类Dev

JSON.parse 中不允许使用哪些字符?

来自分类Dev

有要求Group By子句并且不允许它

来自分类Dev

为什么 toString 不允许 throws 子句

来自分类Dev

SQL语句中不允许使用本地集合类型

来自分类Dev

我如何使用游标中的if条件,因为我们的教授不允许我们在select语句中使用where子句

来自分类Dev

视图不允许在FROM子句中使用子查询,如何在没有子查询的情况下重写我的SQL?

来自分类Dev

XSD限制-空白“替换”,但不允许使用空格

来自分类Dev

Windows不允许我替换文件

来自分类Dev

不允许替换包含奇数引号的匹配项

来自分类Dev

脚本失败,显示“ chmod:...不允许操作”

来自分类Dev

PouchDB / CouchDB复制失败,方法不允许

来自分类Dev

由于不允许GET请求,POST请求失败

来自分类Dev

PouchDB / CouchDB复制失败,不允许使用方法

来自分类Dev

脚本失败,显示“ chmod:...不允许操作”

来自分类Dev

chown失败:不允许操作(与权限有关)

来自分类Dev

CodeIgniter 上传失败 - 不允许文件类型

来自分类Dev

不允许的方法

来自分类Dev

不允许过滤

来自分类Dev

不允许操作

来自分类Dev

“ *不允许模式”

Related 相关文章

热门标签

归档