Подтвердить что ты не робот

Реализация is_constexpr_copiable

Я попытался реализовать шаблон значений, аналогичный std::is_constructible, за исключением того, что он имеет значение true, только когда тип скопирован в среде constexpr (т.е. его конструктор копирования является constexpr). Я пришел к следующему коду:

#include <type_traits>

struct Foo {
    constexpr Foo() = default;
    constexpr Foo(const Foo&) = default;
};
struct Bar {
    constexpr Bar() = default;
    Bar(const Bar&);
};

namespace detail {
template <int> using Sink = std::true_type;
template<typename T> constexpr auto constexpr_copiable(int) -> Sink<(T(T()),0)>;
template<typename T> constexpr auto constexpr_copiable(...) -> std::false_type;
}
template<typename T> struct is_constexpr_copiable : decltype(detail::constexpr_copiable<T>(0)){ };

static_assert( is_constexpr_copiable<Foo>::value, "");
static_assert(!is_constexpr_copiable<Bar>::value, "");

Теперь я спрашиваю себя, соответствует ли это стандарту, поскольку компиляторы, похоже, не согласны с выходом. https://godbolt.org/g/Aaqoah


Изменить (функции С++ 17):

При внедрении несколько другого is_constexpr_constructible_from, с новым типом шаблона автоматического типа non-type С++ 17, я снова нашел разницу между компиляторами, когда разыменовал nullptr в выражении constexpr с помощью SFINAE.

#include <type_traits>

struct Foo {
    constexpr Foo() = default;
    constexpr Foo(const Foo&) = default;
    constexpr Foo(const Foo*f):Foo(*f) {};
};
struct Bar {
    constexpr Bar() = default;
    Bar(const Bar&);
};

namespace detail {
template <int> struct Sink { using type = std::true_type; };
template<typename T, auto... t> constexpr auto constexpr_constructible_from(int) -> typename Sink<(T(t...),0)>::type;
template<typename T, auto... t> constexpr auto constexpr_constructible_from(...) -> std::false_type;
}
template<typename T, auto... t> struct is_constexpr_constructible_from : decltype(detail::constexpr_constructible_from<T, t...>(0)){ };

constexpr Foo foo;
constexpr Bar bar;
static_assert( is_constexpr_constructible_from<Foo, &foo>::value, "");
static_assert(!is_constexpr_constructible_from<Foo, nullptr>::value, "");
static_assert(!is_constexpr_constructible_from<Bar, &bar>::value, "");

int main() {}

https://godbolt.org/g/830SCU

4b9b3361