gpt4 book ai didi

c++ - libc++ is_copy_constructible 对我来说似乎是错误的

转载 作者:可可西里 更新时间:2023-11-01 16:11:33 26 4
gpt4 key购买 nike

is_copy_constructible 的 libc++ 实现是这样的:

template <class _Tp>
struct _LIBCPP_TYPE_VIS_ONLY is_copy_constructible
: public is_constructible<_Tp, const typename add_lvalue_reference<_Tp>::type>
{};

is_copy_constructible 的 C++ 规范很简单:

std::is_copy_constructible specification: std::is_constructible<T, const T&>::value is true.

但是,上面的实现不就是实现了T&const而不是const T&吗?将 const 应用于 add_lvalue_reference 应该没有任何效果,并且至少有一个编译器 (EDG) 以警告的形式识别了这一点。

演示问题的示例程序:

#include <type_traits>

struct ProofTest
{
ProofTest(){}
ProofTest(const ProofTest&) = delete; // is_copy_constructible should use this.
ProofTest(ProofTest&){ } // But instead it's using this.
};

void Proof()
{
static_assert(std::is_copy_constructible<ProofTest>::value == false, "is_copy_constructible bug");
}

在 libstdc++ 下,上述代码编译正常,但在 libc++ 下,static_assert 会触发。

以下是正确的解决方法吗?:

template <class _Tp>
struct _LIBCPP_TYPE_VIS_ONLY is_copy_constructible
: public is_constructible<_Tp, typename add_lvalue_reference<typename std::add_const<_Tp>::type>::type>
{};

这也会影响其他几个 libc++ 类型特征。

最佳答案

同意,感谢错误报告。

更新

Related question: What's the expected value of: std::is_constructible<int&>::value? It's not perfectly clear to me from reading the standard.

标准内容:

For a referenceable type T, the same result as is_constructible<T, const T&>::value, otherwise false.

“可引用类型”基本上不是void。 .我在转述。这不是一个确切的定义。它的意思是可以理解而不是精确。语言律师(包括我自己)可以将其拆解。但为了便于理解,“除 void 之外的任何内容”都足够接近。

所以你的问题变成了,什么是:

std::is_constructible<int&, const (int&)&>::value  // I've used pseudo code

const应用于引用的是一个 no-op ()。应用于左值引用的左值引用是空操作(由于引用折叠)。例如考虑这个非可移植 type_name设施:

#include <type_traits>
#include <memory>
#include <iostream>
#include <cxxabi.h>
#include <cstdlib>

template <typename T>
std::string
type_name()
{
typedef typename std::remove_reference<T>::type TR;
std::unique_ptr<char, void(*)(void*)> own
(
abi::__cxa_demangle(typeid(TR).name(), nullptr,
nullptr, nullptr),
std::free
);
std::string r = own != nullptr ? own.get() : typeid(TR).name();
if (std::is_const<TR>::value)
r += " const";
if (std::is_volatile<TR>::value)
r += " volatile";
if (std::is_lvalue_reference<T>::value)
r += "&";
else if (std::is_rvalue_reference<T>::value)
r += "&&";
return r;
}

int
main()
{
typedef int& T;
std::cout << type_name<const T&>() << '\n';
}

对我来说,这是打印出来的:

int&

所以上面的简化为:

std::is_constructible<int&, int&>::value  // true

应该回答 true因为左值 int应该可以从非常量左值 int 构造.

关于c++ - libc++ is_copy_constructible 对我来说似乎是错误的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20061632/

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