C++ Templates access a function with different types

180 Views Asked by At

So What I'm trying to do is something like this.

I have a template struct like this one:

template <typename T>
struct TemplateTest
{
    void test(T a)
    {
        switch (typeid(boost::any_cast<T>(a)))
        {
        case typeid(int):
            {
                std::cout << "INT";
                break;
            }
        case typeid(float):
            {
                std::cout << "FLOAT";
                break;
            }
        case typeid(double):
            {
                std::cout << "DOUBLE";
                break;
            }
        default:
            {
                std::cout << "OTHER";
                break;
            };
        }
    }
};

And I want to make a vector with different types of that struct and after just use a for-loop to iterate over all my elements and call this function form all of them.

What I would like to have will be something like this:

typedef boost::variant<TemplateTest<float>(), TemplateTest<double>(), TemplateTest<int>() > variant;
typedef std::vector<variant> TestVar;
TestVar d;
d.push_back(new TemplateTest<float>());
d.push_back(new TemplateTest<double>());
d.push_back(new TemplateTest<int>());
for (auto value : d)
{
    value.test(5);
}

Is out there any way to do this without using a specific cast of my type before my function call?

1

There are 1 best solutions below

0
rubenvb On BEST ANSWER

If you want a single function doing different things for a fixed number of types, you want to use overloaded functions, not templates.

void test(int)
{
   std::cout << "INT";
}

If you have a sane default that works for more than one type, you can use template specialization. You already have a struct template wrapping the functions, which is generally a good idea.

template <typename T>
struct TemplateTest
{
    void test(T a)
    {
        std::cout << "OTHER";
    }
};

template<>
struct TemplateTest<int>
{
    void test(int a)
    {
        std::cout << "INT";
    }
};

If, as in this very specific case of oversimplification all that is different is the string, you can use variable templates:

template<typename T>
constexpr char* Typename = "DEFAULT";

template<>
constexpr char* Typename<int> = "INT";

template <typename T>
struct TemplateTest
{
    void test(T a)
    {
        std::cout << Typename<T>;
    }
};

Live example of the last one here. You see that you probably wanted the test function to be static.