gpt4 book ai didi

c++ - C++ 模板中的罗素悖论

转载 作者:IT老高 更新时间:2023-10-28 21:53:30 25 4
gpt4 key购买 nike

考虑这个程序:

#include <iostream>
#include <type_traits>

using namespace std;

struct russell {
template <typename barber,
typename = typename enable_if<!is_convertible<barber, russell>::value>::type>
russell(barber) {}
};

russell verify1() { return 42L; }
russell verify2() { return 42; }

int main ()
{
verify1();
verify2();
cout << is_convertible<long, russell>::value;
cout << is_convertible<int, russell>::value;
return 0;
}

如果某些类型 barber 不能转换为 russell。我们试图通过使其可转换(启用转换构造函数)来创建一个悖论。

输出是 00 与三个流行的编译器,虽然构造函数显然在工作。

我怀疑行为应该是未定义的,但在标准中找不到任何东西。

这个程序的输出应该是什么,为什么?

最佳答案

在重载决议期间,模板实参推导必须实例化默认实参,以获得完整的模板实参集来实例化函数模板(如果可能)。因此 is_convertible<int, russell> 的实例化是必要的,它在内部调用重载决议。 russell 中的构造函数模板在默认模板参数的实例化上下文中。

关键是is_convertible<int, russell>::value计算 russell 的默认模板参数, 自己命名 is_convertible<int, russell>::value .

is_convertible<int, russell>::value
|
v
russell:russell(barber)
|
v
is_convertible<int, russell>::value (not in scope)

core issue 287的(未采用的)决议似乎是主要编译器遵守的事实上的规则。因为实例化点就在实体之前,value的声明在我们评估它的初始化器时不在范围内;因此我们的构造函数有一个替换失败和is_convertiblemain产量 false .问题 287 阐明了哪些声明在范围内,哪些不在范围内,即 value .

Clang 和 GCC 在处理这种情况的方式上确实略有不同。以该 trait 的自定义、透明实现为例:

#include <type_traits>

template <typename T, typename U>
struct is_convertible
{
static void g(U);

template <typename From>
static decltype(g(std::declval<From>()), std::true_type{}) f(int);
template <typename>
static std::false_type f(...);

static const bool value = decltype(f<T>()){};
};

struct russell
{
template <typename barber,
typename = std::enable_if_t<!is_convertible<barber, russell>::value>>
russell(barber) {}
};

russell foo() { return 42; }

int main() {}

Clang 默默地翻译这个。 GCC 提示无限递归链:似乎认为 value确实在默认参数的递归实例化范围内,因此继续实例化 value 的初始化程序一次又一次。然而,可以说 Clang 是正确的,因为 [temp.point]/4 中的当前和起草的相关短语要求 PoI最近的封闭声明之前。 IE。该声明不被视为部分实例化的一部分(尚未)。如果您考虑上述情况,那是有道理的。 GCC 的解决方法:采用一种声明形式,其中在初始化器实例化之前不声明名称。

enum {value = decltype(f<T>()){}};

这与 GCC as well 一起编译.

关于c++ - C++ 模板中的罗素悖论,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45907160/

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