4

I am writing a template function like that:

template<typename T>
std::string EncodeData(int DataType, T Data, std::string ReadCommandID, std::string& ThisID);

The type T that I want to use is some different structs, for example:

struct A
{
    int A_data;
    bool A_data_2;
    // etc.......
};

struct B
{
    double B_data;
    char B_data_2;
    // etc.......
};

I want the function can access different member variables depends on different struct passing to T,so I wrote such code:

template<typename T>
std::string EncodeData(int DataType, T Data, std::string ReadCommandID, std::string& ThisID)
{
    if(std::is_same<T, A>{})
    {
        // Do something with Data.A_data and Data.A_data_2
    }
    else if(std::is_same<T, B>{})
    {
        // Do something with Data.B_data and Data.B_data_2
    }
    // other code.
}

And use it:

A data={100,false};
std::string id;
std::string result = EncodeData<A>(0,data,"read_id_xxxxxxxx",id);

But when I compile it, the following error happened:

error C2039: "B_data": is not a member of "A".    
error C2039: "B_data_2": is not a member of "A".

How can I fix this? Or what else I can do to solve this problem in one single function?

P.S. I'm using MSVC Compiler(Visual Studio 2019)

JeJo
  • 30,635
  • 6
  • 49
  • 88
  • 3
    You want to specialize your template for different `T`. Search for that term and you will find instructions and examples galore. – Ulrich Eckhardt Sep 29 '21 at 11:07
  • 3
    or [constexpr if](https://en.cppreference.com/w/cpp/language/if) – 463035818_is_not_an_ai Sep 29 '21 at 11:09
  • Also your problem seems to me not good to be solvable via templates. Maybe use the visitor pattern instead – RoQuOTriX Sep 29 '21 at 11:10
  • 1
    @UlrichEckhardt Or just make two overloads. Specializing function templates might be [tricky](http://www.gotw.ca/publications/mill17.htm). – Evg Sep 29 '21 at 11:11
  • what works best depends on whether you need to call it only with 2 different types, or there are actually more (and then still it depends whether the number of types is considerably small or should be unbounded) – 463035818_is_not_an_ai Sep 29 '21 at 11:21

1 Answers1

8

What else I can do to slove this problom in one single function?

This is not possible under compiler. However, in C++17 you have if constexpr to do such:

template<typename T>
std::string EncodeData(int DataType, T const& Data, std::string const& ReadCommandID, std::string& ThisID)
{
    if constexpr (std::is_same_v<T, A>)
    {
        // Do something with Data.A_data and Data.A_data_2
    }
    else if constexpr (std::is_same_v<T, B>)
    {
        // Do something with Data.B_data and Data.B_data_2
    }
}

For C++11 you still need two functions. Therefore, I would suggest having a function overload for each, which might be more readable than having templates.

JeJo
  • 30,635
  • 6
  • 49
  • 88