简体   繁体   中英

How to use Structs in Templates as Parameters c++

I saw a video about templates in c++ the other day and it had the following code:

template <typename T>
void someFunction(T num) {
   Print(num);
}

The "Print()" just prints out the var "num" in console. I basically understood how to use templates as parameters. However, I don't know how to use this with Structs, or if it's even possible. I mean something like this:

struct vec2 {
   float x, y;
};

struct vec3 {
   float x, y, z;
};

template <typename T>
void someFunction(T vec);

I want to check in the function whether "vec" is a vec2 or a vec3 and then use it differently. Like this:

if (vec==vec2) {
   //Print x and y
else if (vec==vec3) {
   //Print x, y and z
}

In the end my goal is simply to have a function that I can give 2 different structures to. I already heard about std::is_same and tried it but without any success.

This is actually possible using a type trait and if constexpr :

#include <iostream>
#include <type_traits>

struct vec2 {
   float x, y;
};

struct vec3 {
   float x, y, z;
};

template <typename T>
void someFunction(T vec)
{
   if constexpr (std::is_same_v<T, vec2>) {
      std::cout << vec.x << ' ' << vec.y << '\n';
   }
   else if constexpr (std::is_same_v<T, vec3>) {
      std::cout << vec.x << ' ' << vec.y << ' ' << vec.z << '\n';
   }
}

int main()
{
    vec2 v2 = {1, 2};
    vec3 v3 = {3, 4, 5};
    
    someFunction(v2);
    someFunction(v3);
}

(NB prior to C++17, you'll need std::is_same<T, vec2>::value .)

That being said, in your example, a simple set of function overloads would be more appropriate:

#include <iostream>

struct vec2 {
   float x, y;
};

struct vec3 {
   float x, y, z;
};

void someFunction(vec2 vec) {
   std::cout << vec.x << ' ' << vec.y << '\n';
}

void someFunction(vec3 vec) {
   std::cout << vec.x << ' ' << vec.y << ' ' << vec.z << '\n';
}

int main()
{
    vec2 v2 = {1, 2};
    vec3 v3 = {3, 4, 5};
    
    someFunction(v2);
    someFunction(v3);
}

In both cases, you may wish to consider taking the object by const reference instead of by value (which will copy it).

The answer from Asteroids With Wings gives two solutions, and the second of these is probably what you want. But the first is definitely not; you can achieve the same functionality simply by using function template specialisation:

#include <iostream>

struct vec2 {
   float x, y;
};

struct vec3 {
   float x, y, z;
};

template <typename T>
void someFunction(T vec) ;

template<>
void someFunction<>(vec2 vec)
{
   std::cout << vec.x << ' ' << vec.y << '\n';
}

template<>
void someFunction<>(vec3 vec)
{
   std::cout << vec.x << ' ' << vec.y << ' ' << vec.z << '\n';
}

int main()
{
    vec2 v2 = {1, 2};
    vec3 v3 = {3, 4, 5};
    
    someFunction(v2);
    someFunction(v3);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM