From: Nikolay Ivchenkov on 13 Apr 2010 01:41 According to N3092 - 11/5, "The interpretation of a given construct is established without regard to access control. If the interpretation established makes use of inaccessible member names or base classes, the construct is ill- formed". Does it mean that the following program is ill-formed? #include <type_traits> class X { public: X() {} private: X(int) {} }; int main() { int bool value = std::is_constructible<X, int>::value; } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Nikolay Ivchenkov on 13 Apr 2010 06:55 > #include <type_traits> > > class X > { > public: > X() {} > private: > X(int) {} > }; > > int main() > { > int bool value = > std::is_constructible<X, int>::value; > } Amendment: #include <type_traits> class X { public: X() {} private: X(int) {} }; int main() { const bool value = std::is_constructible<X, int>::value; } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Nikolay Ivchenkov on 13 Apr 2010 16:26 On 14 Apr, 01:57, Daniel Kru"gler <daniel.krueg...(a)googlemail.com> wrote: > > "Given the following function prototype: > > template <class T> > typename add_rvalue_reference<T>::type create(); > > the predicate condition for a template specialization > is_constructible<T, Args...> shall be satisfied if and > only if the following expression CE would be well-formed: > > if sizeof...(Args) == 1, the expression: > static_cast<T>(create<Args>()...) > otherwise, the expression: > T(create<Args>()...)" The correctness of such expressions depends on context where they appear. It would be very surprising if the same member of the same template specialization could have different compile-time values. A library template cannot provide such behavior because immediate context of its use is not available within the template definition: namespace std { template <class T, class... Args> struct is_constructible : integral_constant < bool, __is_constructible(T, Args...) // we don't know immediate context here > { }; } Only core language construct could check accessibility with regard to immediate context. So, if the value of expression "std::is_constructible<X, int>::value" depends on the constructor's accessibility in a given context, then is_constructible is actually not a part of the library, instead it shall be considered as core language construct like dynamic_cast. I need more clear explanation - what exactly affects the value of the expression "std::is_constructible<X, int>::value": the constructor's publicity only or its accessibility in a context where the member "value" of the specialization is accessed? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Mathias Gaunard on 13 Apr 2010 20:18 On 13 avr, 22:57, Daniel Kr�gler <daniel.krueg...(a)googlemail.com> wrote: > std::is_constructible > needs compiler-support Not necessarily. You could use SFINAE to check whether the expressions that defines is_contructible's value are well-formed. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 14 Apr 2010 03:17 On 14 Apr., 13:18, Mathias Gaunard <loufo...(a)gmail.com> wrote: > On 13 avr, 22:57, Daniel Kr�gler <daniel.krueg...(a)googlemail.com> > wrote: > > > std::is_constructible > > needs compiler-support > > Not necessarily. > You could use SFINAE to check whether the expressions that defines > is_contructible's value are well-formed. Nope, SFINAE is *not* access-tolerant. Just try template<class T> struct HasStaticFoo { typedef char No; typedef char(&Yes)[2]; template<class U, class = decltype(U::foo())> static Yes test(void*); template<class> static No test(...); static const bool value = sizeof(test<T>(0)) == sizeof(Yes); }; struct S { static void foo(); }; struct D {}; class X { static void foo(); }; static_assert(HasStaticFoo<S>::value, "Ouch"); static_assert(!HasStaticFoo<D>::value, "Ouch"); static_assert(!HasStaticFoo<X>::value, "Ouch"); int main() {} with a recent C++0x capable compiler and you will notice that the error for X is *not* related to a violation of static_assert. is_constructible and is_convertible are traits that *require* compiler support, because they were intended to cope with access restrictions. I haven't tested recent implementations but I would expect that most of them still behave like normal SFINAE-based realizations, which - strictly speaking - are non-conforming, but the easiest to do for the moment. 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! ]
|
Next
|
Last
Pages: 1 2 Prev: Iterating over a directory Next: [Help]An explicit instantiation of function template |