1

I can easily capture and enumerate over the parameters of a method or function, by using a variadic template such as:

template<typename RT, typename ...Args>
class MyFunctor< RT (*)(Args ... args)>
{
    //Count the number of arguments
    static constexpr int const arity=sizeof ...(Args);

    //Create something to store the arguments in
    std::tuple<Args...> _arguments;

}

I can then create template methods that can iterate through the argument list and eventually invoke a pointer to a real function using the _agrument tuple.

I understand that constructors are nameless, but are they also typeless? Is there a way to get the 'type' of a constructor so that I can do something similar to what I can do with functions and methods?

In C++ 03 I could capture the type of a constructor with the following (using GCC 3.3):

TypeDefT< typeof( MyClass::MyClass(int i) ) *>

By placing the pointer syntax after the typeof() statement, I could then treat the constructor signature like the type of a normal function pointer.

I would then add a create method to the FunctionPointer template that could then be called with a mere list of parameters, and new MyClass( p1, p2, p3 ) could happen.

However, it seems with C++ 17 there isn't a way to get the type of a constructor like I seemed to be able to with C++ 03 nor like I can with functions in C++ 17. Is there a way to do this?

Thank you

  • First, `typeof` [isn’t part of C++03](https://stackoverflow.com/q/1986418/8586227) (or any other standard). Second, unless you could obtain a “constructor pointer” from just a type name (despite the likely overloading), I don’t see what this would get you beyond just writing `TypeDefT` manually. Third, things like `std::make_unique` work just fine without needing to *analyze* any constructor signature; why can’t you do the same? – Davis Herring May 03 '19 at 02:53
  • I need to be able to iterate over the parameters to a constructor and know how many parameters it has. This allows arbitrary serialized data to contain requests to instantiate a class and (from the data) pass parameters. Knowing at compile time the parameters that a constructor can take seems to be necessary so the deserialization/class creation method can know how many parameters to expect in the data stream and gracefully deal with mismatches. It would be handy to have the compiler do this as in the short example above. I will take your suggestion and look closely at make_unique, thanks – Kevin Stallard May 03 '19 at 04:06
  • ...and wanted to do it by using the name of the constructor along with its prototype. Could do this manually for sure, but was looking for a way that would allow the compiler to deduce the signature so the risk of making a mistake would be reduced. – Kevin Stallard May 03 '19 at 04:34
  • The deserialization use case is totally legitimate—but unless your class had exactly one constructor (which never actually happens unless it’s a copy constructor!), how can you do better than `MakeFrom(stream)` anyway? The compiler will of course check that you can indeed construct from the types you use (although it will allow implicit conversions, which could be a good or a bad thing). You could have each class define a tuple of its serialization types to avoid stating them separately at the call site, although then you could just define a static function per class. – Davis Herring May 03 '19 at 04:35
  • Good point. I was spoiled by the loose adherence to standards by gcc 3.3 because I could just plop in the constructor prototype. Made a macro for it and typeof() magically turned that into a function type that then kicked off a specialized template class with the parameters and parameter types of the constructor....I didn't have to manually use the <>'s to do it....again, I realize I was spoiled :) – Kevin Stallard May 03 '19 at 04:55
  • I think that [`magic_get`](https://github.com/apolukhin/magic_get) has stuff to detect constructor parameters in some cases. – Jarod42 May 03 '19 at 08:32

1 Answers1

1

Constructors do not have types. Have you noticed that you are not allowed to write a return type when declaring a constructor?

Unfortunately, there is no way to get something like a function pointer to a constructor. Your "C++03" solution is not standard, and GCC 3.3 is a very old compiler; back in those days, GCC had many non-portable extensions, and most of them have been removed.

You need to find a different way of doing the actual thing that you want to do. As pointed out in the comments to the question, generic code usually doesn't need to "know" a constructor's signature.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • Yeah, I knew typeof is non-standard and was risking this working on a newer compiler back when I wrote it initially. I did like what it was able to do for me in gcc 3.3. Your answer is what I was looking for, wondering if our C++ standards committee decided to deprive constructors of having types. Sounds like the answer is yes. Thanks @Brian. – Kevin Stallard May 03 '19 at 04:09