std :: is_constructible для неполных типов - PullRequest
30 голосов
/ 24 апреля 2019

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

#include <iostream>

class A;

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

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

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

Ответы [ 3 ]

26 голосов
/ 24 апреля 2019

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

[meta.unary.prop]

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

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

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


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

18 голосов
/ 24 апреля 2019

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

Cppreference состояния:

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

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

9 голосов
/ 24 апреля 2019

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

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

Акцент шахты

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...