Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 413
R_Kapp Avatar asked Apr 24 '19 13:04

R_Kapp


People also ask

What is an incomplete type?

An incomplete type can be: 1 A structure type whose members you have not yet specified. 2 A union type whose members you have not yet specified. 3 An array type whose dimension you have not yet specified. More ...

What is a constructible type in Java?

For this class, a constructible type is a type that can be constructed using a particular set of arguments. is_constructible inherits from integral_constant as being either true_type or false_type, depending on whether T is constructible with the list of arguments Args. A complete type, or void (possible cv-qualified), or an array of unknown bound.

What is is_constructible in C++?

Args> struct is_constructible; For this class, a constructible type is a type that can be constructed using a particular set of arguments. is_constructible inherits from integral_constant as being either true_type or false_type, depending on whether T is constructible with the list of arguments Args.

How to create an incomplete array type in C++?

To create an incomplete array type, declare an array type without specifying its repetition count. For example: To complete an incomplete array type, declare the same name later in the same scope with its repetition count specified, as in


1 Answers

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.

like image 68
StoryTeller - Unslander Monica Avatar answered Sep 20 '22 12:09

StoryTeller - Unslander Monica