9

It's easy to create a method/function parametrized on the type of an unnamed struct. It is also easy to get the type after the struct's definition.

struct Foo {
  template <typename T> Foo(T*) { /* we have access to T here */ }
}
template <typename T> void baz(T*) { /* we have access to T here */ }

template<typename T> struct Bar {
  /* we have access to T here */
};

void test() {
  struct {
    Foo foo { this }; // access in a constructor
    void test() { baz(this); } // access in a function
  } unnamed;
  Bar<decltype(unnamed)> bar; // access after definition
}

But is there any "magic" that could allow the use of unnamed's type at the struct scope, or in a static method - not merely within its constructor/instance method or after an instance is declared? It's trivial when the struct is named:

// How to make it work with S absent (an unnamed struct) ?
struct S {
  Bar<S> foo; // how to get our type in an unnamed struct?
  static void wrapper(void * instance) {
    static_cast<S*>(instance)->method(); // how to get our type in an unnamed struct?
  }
  void method() { ... }
} would_be_unnamed;

This question was motivated by a question about how to implement a destructor in an unnamed struct. The trivial solution there was to wrap a named struct in an unnamed one - such wrapper can then be used in macros without clashing with any other types, etc.

struct { struct S { ... } s; } unnamed;

Solving the type access conundrum would allow a different solution to the motivating question.

Community
  • 1
  • 1
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • 1
    Why don't you give it a name? If there's an issue with scoping (e.g. when using a macro), can you wrap it in a lambda, `[]{ struct NAME { ... }; return NAME(); }()`? – dyp Aug 26 '15 at 21:50
  • @dyp It's not in search of a solution to a practical problem - or, rather, the practical problem (that of putting constructors/destructors in a nameless struct) has a simple elegant solution (a nested named class) that doesn't need this problem to be solved. I'm just wondering if there is a way to do it, that's all. – Kuba hasn't forgotten Monica Aug 26 '15 at 21:52
  • 2
    Related: [Can I implement an autonomous `self` member type in C++?](http://stackoverflow.com/q/21143835/) – dyp Aug 26 '15 at 21:53
  • @dyp Yeah, that's a similar problem, but not the same one: it is implemented using a macro that won't work for an unnamed struct :( – Kuba hasn't forgotten Monica Aug 26 '15 at 21:57
  • I'm kind of confused about the anonymous structs, I keep reading things like "*There are no anonymous structs in standard C++ (only anonymous unions)*", and also there's a [topic about it](http://stackoverflow.com/questions/14248044/are-anonymous-structs-standard-and-really-what-are-they). – PaperBirdMaster Aug 27 '15 at 08:05
  • @PaperBirdMaster I'm talking about unnamed structs, not anonymous structs. They are two very different birds. Note the pronounced absence of the word "anonymous" in the question :) – Kuba hasn't forgotten Monica Aug 27 '15 at 12:57
  • @KubaOber then my confusion is even greater "anonymous" and "unnamed" aren't the same thing? aren't synonyms? (english Isn't my first language hence the confusion). – PaperBirdMaster Aug 27 '15 at 13:55
  • @PaperBirdMaster We're using very specific technical terms. What the English dictionary says isn't relevant here: both *anonymous* and *unnamed* have their standard-given, specific meanings. Anonymous structs are really a C99 beast, I don't know offhand if C++11 even speaks of them. When speaking about language semantics, you should never use synonyms for words that are used according to their meaning as given in the language standard. For example, the C++11 standard might not use the word "anonymous" anywhere, but the C standard does and you become very hard to understand if you mix them. – Kuba hasn't forgotten Monica Aug 27 '15 at 14:18
  • @KubaOber got it, thanks for the explanation :) – PaperBirdMaster Aug 27 '15 at 15:10

1 Answers1

4

Something like this, maybe?

The idea is that you actually have two unnamed structs. Firstly, unnamed contains all the actual code/data and stuff. Then there is unnamedWrapper that, being able to use decltype over unnamed, is just a completely-forwarding (even for constructors!) wrapper around unnamed, with the single speciality that it exports unnamed's type through a typedef.

#include <cstddef>

template<typename T>
size_t templatedSizeof() {
    return sizeof(T);
}

struct {
    char    something;
    short   somethingElse;
    int     moreGargabe;
    long    evenMoreUselessGarbage;
} unnamed;

struct : public decltype(unnamed) {
    typedef decltype(unnamed)   TheType;

    using TheType::TheType; // Use same constructors
} unnamedWrapper;
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
3442
  • 8,248
  • 2
  • 19
  • 41