Why can I use my own default constructor in decltype ()?

Take a look at the code:

#include <iostream> #include <utility> class test { private: test() { } public: test foo() { return *this; } static const char *name() { return "test"; } }; int main() { std::cout << decltype(test().foo())::name() << std::endl; // 1 std::cout << decltype(std::declval<test>().foo())::name() << std::endl; // 2 } 

I was expecting the line // 1 could not be compiled because the default constructor test is private.

However, it works well. I tested it on my g ++ 4.8.3 with -Wall -Wextra -Werror -pedantic at a loss, but it works fine without any errors or warnings.

(Also, it seems to work well in GCC 4.9.1.)

From this page , I think we can use the default private constructor if the expression is not evaluated. So, I checked the following to verify this.

 #include <iostream> #include <utility> class test { private: test(int) { } public: test foo() { return *this; } static const char *name() { return "test"; } }; int main() { std::cout << decltype(test().foo())::name() << std::endl; // 1 std::cout << decltype(std::declval<test>().foo())::name() << std::endl; // 2 } 

(live example)

As expected, it was not compiled.

But .... why ?? How is this possible? Can we use private elements in an invaluable expression? Or is there a special rule for default constructors? Could you explain to me why?

+7
c ++ language-lawyer private-members c ++ 11 decltype
source share
1 answer

It should not compile. C ++ 11 [class.temporary] means creating a temporary object:

12.2 / 1 Even when the creation of a temporary object is not appreciated or otherwise avoided, all semantic restrictions must be respected as if the temporary object was created and subsequently destroyed. [Note: even if there is no call to the constructor of the destructor or copy / move, all semantic restrictions , such as accessibility and delete function, must be met. However, in the special case of a function call used as the operand of the decltype specifier, no time constraints are introduced; therefore, the above does not apply to the value of any such function call. - final note]

Thus, even if you are not appreciated, you are still limited by the availability of any functions (including constructors) needed to create and destroy temporary ones. The last sentence of the note clarifies that a function such as declval can be used to prevent this obstacle.

+11
source share

All Articles