简体   繁体   中英

How to determine the type of a passed vector to a template function

Hi guys maybe you can help me out on this,

I've two vectors (vecInt, vecDouble). Obviously one is of sort int and the other is of sort double.

But how do I check the types of those vectors in the if and the else if?

    if (TYPE OF VECTOR == INT) {
        std::cout << "vecInt: ";
    }
    else if (TYPE OF VECTOR == DOUBLE) {
        std::cout << "vecDouble: ";
    }

But how do I check the types of those vectors in the if and the else if?

You don't. That is not to say you can't, only that you shouldn't. This sort of branching is not going to give you the solution you want, 9 out of 10 times. A superior choice is overloading. Instead of adding a branch, add a call to a helper function, one that you then overload to get the behaviors you want.

It would look like this:

#include <vector>
#include <iostream>

template<typename T>
void output_helper(std::vector<T>*) {}

void output_helper(std::vector<int>*) {
    std::cout << "vecInt: ";
}

void output_helper(std::vector<double>*) {
    std::cout << "vecDouble: ";
}

template <typename T>
void output(std::vector<T>* vO) {
    output_helper(vO);

    for (size_t i = 0; i < vO->size(); i++) {
        std::cout << (*vO).at(i) << " ";
    }
    std::cout << std::endl;
}

int main() {
    std::vector<int> v{1, 2, 3};
    output(&v);
    return 0;
}

Which indeed outputs

vecInt: 1 2 3 

As you can see live . A major bonus to overloading is that you can extend the behavior of output without modifying it. Simply add an overload for another vector type.

And by the way, consider ditching the pass by pointer, and pass by reference, as one would in idiomatic C++.

You can use type traits in C++11 and C++14:

#include <type_traits>

if (std::is_same<T, int>::value) {
    std::cout << "vecInt: ";
}
else if (std::is_same<T, double>::value) {
    std::cout << "vecDouble: ";
}

Note that this is a runtime check, but the compiler should be able to optimize it away.

In C++17, you can instead use if constexpr , which makes this a guaranteed compile-time check with no runtime overhead, and you can also use the _v version of is_same in order to not have to write ::value every time:

if constexpr (std::is_same_v<T, int>) {
    std::cout << "vecInt: ";
}
else if constexpr (std::is_same_v<T, double>) {
    std::cout << "vecDouble: ";
}

In practice, however, even the former version should end up with no runtime check, as the compiler will optimize away the branches, as the if clauses are compile-time constant expressions. In each template specialization, the compiler can see that one of the branches can never be taken, and will therefore delete the branch.

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