1

Consider the following C++ code, where member foo has a private type:

class Object {
private:
    struct MyPrivateThing {
        long double Member;
    };
    using Type = MyPrivateThing;
public:
    Type foo = {32.45L};
    // MyPrivateThingFoo also works
};

int main() {
    // Object::Type f = {34.567L}; ERROR: Object::Type is private
    decltype(Object::foo) thingy = {945.67L}; // Fine
    auto x = Object().foo;
    return x.Member * thingy.Member;
}

Although this code is legal C++ and compiles fine, it seems a bit counter-intuitive —Object::Type is private and not accessible outside the class, yet we can still indirectly refer to it by using auto to get a variable of that type.

It would seem that the more straightforward thing to do would be to just make every public member have a public type.

Can you think of any valid use-cases for this pattern?

saxbophone
  • 779
  • 1
  • 6
  • 22
  • 1
    If somewhere else you want to create an instance of that type, do you think that's possible? – Sam Varshavchik Jun 05 '22 at 20:56
  • You can always use `auto` from the client side completely anonymously, and pass it back to the public interface. It's much like using opaque handles in c code. – πάντα ῥεῖ Jun 05 '22 at 20:57
  • oh, you can use `long double` directly too. I don't see your point – Aykhan Hagverdili Jun 05 '22 at 20:58
  • 1
    I don't think there is a point of having a public method with a private type. At least I never used it. But I'm curious to see if that could make sense for others. – prapin Jun 05 '22 at 20:58
  • @SamVarshavchik Good question! I would assume I could use `decltype` to accomplish what you speak of. What do you think? – saxbophone Jun 05 '22 at 20:58
  • @AyxanHaqverdili `long double` is just an example, I know I can use that directly. For this example, I am using `long double` as a placeholder for `InsertYourCustom` – saxbophone Jun 05 '22 at 20:59
  • 2
    The *alias* is private but the aliased *type* (`long double`) isn't. One purpose (which the comment in your code appears to verify) would be to confuse IDE extensions, like IntelliSense (but there are many ways of doing that). – Adrian Mole Jun 05 '22 at 21:02
  • @AdrianMole Ah, that makes sense, thanks. I am interested now to see if I will get different results if the aliased type is truly private (such as a newly-created aggregate type)... – saxbophone Jun 05 '22 at 21:05
  • 2
    @AdrianMole Another purpose is simply to save typing in the header file without making the alias part of the interface contract. `private: using abc = Annoyingly::Bloviated::Concept; public: abc GetConcept();` The return type is `Annoyingly::Bloviated::Concept` but to save typing in the header file, they create the alias `abc` for internal purposes. – Raymond Chen Jun 05 '22 at 21:06
  • 1
    @RaymondChen Sounds like a regular Microsoft trick. :-) – Adrian Mole Jun 05 '22 at 21:07
  • I have updated the code to reflect new discoveries made in the course of this comment thread, thanks all. The nature of the question remains unchanged by the edit to the code. – saxbophone Jun 05 '22 at 21:10
  • @RaymondChen how would I know what the return type is "officially" supposed to be if it's not in there when I look at the function declaration? That just sounds like a bad idea and many users are going to be upset by your bloated interface that saved your a couple keystrokes. – Aykhan Hagverdili Jun 05 '22 at 21:11
  • 1
    @AyxanHaqverdili The formally supported return type is in the documentation. The header file is not documentation. – Raymond Chen Jun 05 '22 at 21:13
  • @RaymondChen the header file is supposed to be the documentation. When I start typing, my IDE recommends stuff from the header file, it doesn't go dig up your website for appropriate documentations. That typedef trick is sounds like a very unpleasant experience for everyone involved. – Aykhan Hagverdili Jun 05 '22 at 21:15

0 Answers0