Re: Type traits and accessibility
On 18 Apr., 00:03, Nikolay Ivchenkov <ts...@mail.ru> wrote:
On 16 Apr, 23:01, Daniel Kr?gler <daniel.krueg...@googlemail.com>
wrote:
I would say, that this is probably a border-case and the wording
could (and should) be improved. I'm going to file this as an NB
comment.
Note that publicity of _any_ member function directly invoked by the
expression CE should be checked.
#include <iostream>
#include <type_traits>
class A
{
~A() {} // private
};
class B
{
public:
B() {}
private:
B(B const &) {}
};
class C
{
operator int() { return 0; } // private
};
struct X
{
X(A) {}
X(B) {}
X(int) {}
};
int main()
{
std::cout << std::is_constructible<X, A>::value;
std::cout << std::is_constructible<X, B>::value;
std::cout << std::is_constructible<X, C>::value;
}
Sure.
Note also that well-formed expression could render the program ill-
formed. In particular, the program is ill-formed if an undefined
function is used:
#include <type_traits>
struct Y
{
Y(int); // has no definition
};
int main()
{
// OK
!std::is_constructible<Y, int>::value ?
(void)Y(0) : (void)sizeof Y(0);
// renders the program ill-formed
std::is_constructible<Y, int>::value ?
(void)Y(0) : (void)sizeof Y(0);
}
[I'm referring to your revised version in the
following]
Not really. Your test program which contains
use<!std::is_constructible<Y, int>::value>();
is ill-formed, because the definition of the
constructor is *missing*, but it is *not* ill-
formed, because an undefined entity is *used*.
Note that this is an important difference and
it ensures that the definition of is_constructible
and is_convertible based on a well-formed
expression "works" even if any of the used
entities is potentially not defined. This
also means that these support trait definitions
are neutral versus potentially missing definitions,
which is exactly intended (otherwise they would
not be implementable).
3.2/3:
"Every program shall contain exactly one definition
of every non-inline function or variable that is
used in that program; no diagnostic required. [..]"
So, it is very important to distinguish "ill-formed program" and "ill-
formed expression".
Not really. The core language does not distinguish
between a well/ill-formed program or a well/ill-
formed expression. If the core language speaks
if an ill-formed expression this is just a short
wording of "A program that contains this expression
is ill-formed".
However, there are several places in the
specification where the notion of ill-formedness applies to entire
program when it presumably should apply to a certain construct. For
example:
4.10/3:
"A prvalue of type "pointer to cv D", where D is a class type, can be
converted to a prvalue of type "pointer to cv B", where B is a base
class (Clause 10) of D. If B is an inaccessible (Clause 11) or
ambiguous (10.2) base class of D, a program that necessitates this
conversion is ill-formed."
This wording doesn't say that an expression or an initialization which
necessitates ambiguous derived-to-base pointer conversion is ill-
formed. How shall std::is_constructible handle this case?
#include <iostream>
#include <type_traits>
struct B {};
struct B1 : B {};
struct B2 : B {};
struct D : B1, B2 {};
int main()
{
std::cout << std::is_constructible<B *, D *>::value;
}
Another example:
8.5/8:
"A program that calls for default-initialization or value-
initialization of an entity of reference type is ill-formed."
What is the result of the following program?
#include <iostream>
#include <type_traits>
int main()
{
std::cout << std::is_constructible<int &>::value;
}
There is no problem with all of these examples, they
are covered by the definition of an ill-formed
expression equivalent being to an ill-formed program.
The same questions should be addressed to the use of SFINAE principle
that is also based on the notion of ill-formedness of a particular
constructs.
For the same reasons as mentioned above this is
also no special problem for SFINAE, based on
14.9.2/8. A simple way of describing how
is_constructible and is_convertible are defined
is to say: "Just like SFINAE, except that access
checking is done" (We already have agreed that
this access checking is supposed to be context-free
and is intended to allow for public access only).
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]