Thr*_*Bit 10 c++ type-traits c++11 libc++
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>
{};
Run Code Online (Sandbox Code Playgroud)
is_copy_constructible的C++规范很简单:
std::is_copy_constructible specification: std::is_constructible<T, const T&>::value is true.
Run Code Online (Sandbox Code Playgroud)
但是,上面的实现不是实现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");
}
Run Code Online (Sandbox Code Playgroud)
在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>
{};
Run Code Online (Sandbox Code Playgroud)
这也会影响其他一些libc ++类型的特征.
同意,谢谢bug报告.
更新
相关问题:预期价值是
std::is_constructible<int&>::value多少?从阅读标准来看,我并不十分清楚.
标准说的是:
对于可引用类型
T,结果与is_constructible<T, const T&>::value否则相同false.
"可参考类型"基本上只是一个void.我在解释.这不是一个确切的定义.与精确相反,它是可以理解的.语言律师(包括我自己)可以将其撕裂.但为了便于理解,"除了"之外的任何东西都void足够接近.
所以你的问题变成了:
std::is_constructible<int&, const (int&)&>::value // I've used pseudo code
Run Code Online (Sandbox Code Playgroud)
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';
}
Run Code Online (Sandbox Code Playgroud)
对我来说这打印出来:
int&
Run Code Online (Sandbox Code Playgroud)
所以上面简化为:
std::is_constructible<int&, int&>::value // true
Run Code Online (Sandbox Code Playgroud)
应该回答,true因为左值int应该可以从非常量左值开始构造int.
| 归档时间: |
|
| 查看次数: |
396 次 |
| 最近记录: |