R_Kapp
R_Kapp

Reputation: 2858

std::is_constructible on incomplete types

I have the following code:

#include <iostream>

class A;

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

When I use GCC 8.3, this code compiles. However, when I use Clang 8.0, I get a compilation error that incomplete types cannot be used in type traits.

Which one is correct? Am I allowed to use is_constructible on an incomplete type (with an expected value of false), or am I not allowed to?

Upvotes: 33

Views: 2067

Answers (3)

The behavior is undefined.

[meta.unary.prop]

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

T and all types in the parameter pack Args shall be complete types, (possibly cv-qualified) void, or arrays of unknown bound.

That's a precondition of the meta-function. A contract that your code violates. libc++ is being generous by notifying you.


Mind you, that putting that precondition there and leaving it undefined otherwise is for a reason. A program where two points of instantiation of a template have different meanings is ill-formed NDR. The only sane course of action is demand complete types. And after all, that's when the trait is most useful anyway.

Upvotes: 27

NathanOliver
NathanOliver

Reputation: 180945

Your code has undefined behavior. Per [meta.unary.prop] table 47 std::is_constructible requires

T and all types in the template parameter pack Args shall be complete types, cv void, or arrays of unknown bound.

emphasis mine

Upvotes: 8

Nellie Danielyan
Nellie Danielyan

Reputation: 1011

Your code causes undefined behavior.

Cppreference states:

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

T and all types in the parameter pack Args shall each be a complete type, (possibly cv-qualified) void, or an array of unknown bound. Otherwise, the behavior is undefined.

Upvotes: 18

Related Questions