2

I'm confused by these three things. Here is a simple example:

template<typename T>
void func(T t) {
    if (typeid(T) == typeid(int)) {
        std::cout << "f - int" << std::endl;
    } else {
        std::cout << "f - other" << std::endl;
    }
}

template<typename T>
void func2(T t) {
    if (std::is_same<T, int>::value) {
        std::cout << "f2 - int" << std::endl;
    } else {
        std::cout << "f2 - others" << std::endl;
    }
}

template<typename T>
void func3(T t) {
    if constexpr (std::is_same<T, int>::value) {
        std::cout << "f3 - int" << std::endl;
    } else {
        std::cout << "f3 - other" << std::endl;
    }
}

int main() {
    func(1);
    func('a');
    func2(1);
    func2('a');
    func3(1);
    func3('a');

    return 0;
}

The output is

f - int
f - others
f2 - int
f2 - others
f3 - int
f3 - others

So it works as expected. But I kind of don't know which one should be used in which case.

As my understanding, typeid in the first one is totally about runtime. That's all I know. But template is about compile time, right? So does it mean that the func is a stupid design?

How about the func2 and the func3? Are they exactly the same thing? Are they all about compile time? Or the func2 is still about runtime?

Yves
  • 11,597
  • 17
  • 83
  • 180

1 Answers1

1

As you said, funcs checks are always at runtime.

For func3, the checks are always at compile time. The compiler will generate different function bodies when it it instantiated:

template <>
void func3<int> (int t) {
    std::cout << "f3 - int" << std::endl;
}

vs

template <>
void func3<float> (float t) {
    std::cout << "f3 - other" << std::endl;
}

For func2 the answer is "it depends". At -O0 (no optimization) most compilers will defer the check to runtime. But as you up the optimization level, the compiler may notice that the if condition is a compile time constant, and optimize away the if entirely. Some exploration with Compiler Explorer should tell you what your compiler of choice will do.

Marshall Clow
  • 15,972
  • 2
  • 29
  • 45
  • OK. So `func2` and `func3` are much better than `func`. `func2` for c++11 and 14, `func3` for c++17. – Yves Aug 12 '21 at 02:44