typeid vs std::is_same vs if constexpr

typeid vs std::is_same vs if constexpr

我对这三件事感到困惑。这是一个简单的例子:

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;
}

输出为

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

所以它按预期工作。但是我有点不知道在什么情况下应该使用哪个。

据我了解,第一个中的 typeid 完全是关于运行时的。这是我所知道的一切。但是模板是关于编译时间的,对吧?那么这是否意味着 func 是一个愚蠢的设计?

func2func3 怎么样?它们是完全一样的东西吗?它们都是关于编译时间的吗?或者 func2 仍然是运行时?

如您所说,funcs 检查总是在运行时进行。

对于func3,检查总是在编译时进行。编译器在实例化时会生成不同的函数体:

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

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

对于func2,答案是“视情况而定”。 在 -O0(无优化)大多数编译器会将检查推迟到运行时。但是当您提高优化级别时,编译器 可能 注意到 if 条件是一个编译时间常量,并完全优化掉 if 。使用 Compiler Explorer 进行一些探索应该会告诉您您选择的编译器将做什么。