Реализация lib_ ++ is_copy_constructible выглядит так:
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 проста:
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 using this.
};
void Proof()
{
static_assert(std::is_copy_constructible<ProofTest>::value == false, "is_copy_constructible bug");
}
В libstdС++ приведенный выше код компилируется ОК, но под libС++ запускается 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>
{};
Это также влияет на некоторые другие черты типа libС++.