std :: is_constructible для неполных типов

У меня есть следующий код:

#include <iostream>

class A;

int main()
{
    std::cout << std::is_constructible<A>::value << std::endl;
}

Когда я использую GCC 8.3, этот код компилируется. Однако, когда я использую Clang 8.0, я получаю ошибку компиляции, что неполные типы не могут быть использованы в чертах типа.

Который правильный? Могу ли я использовать is_constructible для неполного типа (с ожидаемым значением false) или мне нельзя?

Ответ 1

Поведение не определено.

[meta.unary.prop]

template <class T, class... Args> struct is_constructible;

T и все типы в наборе параметров Args должны быть полными типами (возможно, cv-квалифицированными) void или массивами с неизвестной границей.

Это предварительное условие мета-функции. Контракт, который нарушает ваш код. libc++ щедро уведомляет вас.


Имейте в виду, что поместить это предварительное условие и оставить его неопределенным, иначе есть причина. Программа, в которой две точки создания шаблона имеют разные значения, является плохо сформированным отчетом о недоставке. Единственный вменяемый ход действий - требовать полных типов. И в конце концов, это когда черта наиболее полезна в любом случае.

Ответ 2

Ваш код вызывает неопределенное поведение.

Соотношение состояний:

template< class T, class... Args > struct is_constructible;

T и все типы в наборе параметров Args должны представлять собой полный тип (возможно, cv-квалифицированный) void или массив с неизвестной границей. В противном случае поведение не определено.

Ответ 3

Ваш код имеет неопределенное поведение. Согласно таблице [meta.unary.prop] 47 std::is_constructible требуется

T и все типы в пакете параметров шаблона Args должны быть полными типами, cv void или массивами с неизвестной границей.

акцент мой