Ответ 1
Проблема с вашим кодом заключается в том, что мы просто создали экземпляр is_constructible
в контексте, где он получает ответ неправильно. Любое кэширование кода шаблона может привести к ошибкам - попробуйте распечатать is_constructible
по тем же параметрам после вызова конструктора! Вероятно, это ошибочно.
Живой пример, как это может пойти не так. Обратите внимание, что претензии C
не могут быть построены из int&
, несмотря на то, что сделали это на предыдущей строке.
struct C {
C(const char*, size_t) {}
template <class... Ts,
typename = std::enable_if_t<!std::is_constructible<C, Ts&&...>::value>
>
C(Ts&&... ) { }
};
int main() {
int a = 0;
C x{a};
std::cout << std::is_constructible<C, int&>{} << '\n';
}
упс.
Я подозреваю, что это может быть нарушение ODR - два определения is_constructible
имеют разные типы в разных местах? Или, может быть, нет.
Также опубликовано решение исходной проблемы, которая не имеет этой проблемы.