【问题标题】:typeid vs std::is_same vs if constexprtypeid vs std::is_same vs if constexpr
【发布时间】:2021-08-12 02:10:15
【问题描述】:

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

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 仍然是关于运行时的?

【问题讨论】:

    标签: c++11 templates c++17 runtime if-constexpr


    【解决方案1】:

    正如你所说,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 进行一些探索应该会告诉您您选择的编译器会做什么。

    【讨论】:

    • 好的。所以func2func3func 要好得多。 func2 用于 c++11 和 14,func3 用于 c++17。
    猜你喜欢
    • 1970-01-01
    • 2016-07-24
    • 1970-01-01
    • 2013-08-18
    • 2021-01-31
    • 2012-11-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多