46

How can I pass a variable type to a function? like this:

void foo(type){
    cout << sizeof(type);
}
user3325976
  • 799
  • 1
  • 6
  • 16
  • This is explained in any [good c++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – Jason Oct 06 '22 at 11:25

4 Answers4

62

You can't pass types like that because types are not objects. They do not exist at run time. Instead, you want a template, which allows you to instantiate functions with different types at compile time:

template <typename T>
void foo() {
  cout << sizeof(T);
}

You could call this function with, for example, foo<int>(). It would instantiate a version of the function with T replaced with int. Look up function templates.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • 4
    Only do this if you do not care about compile speed. – Ray Garner Jan 17 '17 at 06:32
  • @RayGarner how do you mean? Aren't two template instantiations would only be as expensive as two classes right? My understanding is that templates increase compile time because of the hidden classes, not because templates are somehow expensive. – TankorSmash Jan 14 '18 at 20:33
  • 2
    @TankorSmash Right well scale is the point as long as its small enough project and scale you have no need to really worry about it. However every small project becomes a big one so just in case any FNG were to read that just wanted them to be aware of the trade off in compile times. – Ray Garner Jan 22 '18 at 05:33
  • This can be achieved using macros actually - I've added an answer below... (Sorry for reviving this post after 8 years...) – Myrddin Krustowski Oct 06 '22 at 11:25
23

As Joseph Mansfield pointed out, a function template will do what you want. In some situations, it may make sense to add a parameter to the function so you don't have to explicitly specify the template argument:

template <typename T>
void foo(T) {
  cout << sizeof(T)
}

That allows you to call the function as foo(x), where x is a variable of type T. The parameterless version would have to be called as foo<T>().

microtherion
  • 3,938
  • 1
  • 15
  • 18
2

A bit late - but it can be achieved using macros - like this:

#define foo(T) std::cout << sizeof(T)
...
foo(MyType);
  • 1
    A section of C++ purists hate macros as their pastime and full time. But, I always cast my vote in favor of a macro, if it can be as cute and short like this. – Seshadri R Aug 22 '23 at 15:46
  • @SeshadriR I don't see any *practical* use for this macro. – Wolf Aug 23 '23 at 14:27
  • @Wolf I have used the macro in one of my programs, as I was struggling to templatize my requirement. I couldn't reproduce it here, as introducing a code block inside my comment proved more insurmountable than writing the code itself elsewhere. How much this is of "practical" use depends on the individual programmer and his/her immediate need. – Seshadri R Aug 24 '23 at 17:44
  • 1
    Okay, you got me there! But *this* is the kind of macro I often use to figure out things like that: `#define TRACE(arg) std::cout << #arg << ": " << arg << "\n";` – and it can also be used as `TRACE(sizeof (T))`. – Wolf Aug 25 '23 at 15:20
  • @Wolf Till I saw your comment, I thought that the arguments to a macro should only be identifiers. Now I learn that they can be used with keywords or operators like **sizeof**. Sincere thanks for the enlightenment. – Seshadri R Aug 26 '23 at 15:57
  • @SeshadriR You are welcome. Please also note the usage of the single `#` within a macro definition: it turns whatever you pass to it into a string literal (before the compiler sees it). – Wolf Aug 26 '23 at 17:18
  • @Wolf Yes, I knew and used the stringizing macro already. – Seshadri R Aug 27 '23 at 13:20
1

You can do this:

#include <typeinfo>

template<class input>
void GetType(input inp){
    auto argumentType = typeid(inp).name();
}

Seems like it's not exactly you are looking for, but it may help.

Jenia
  • 374
  • 1
  • 4
  • 15