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
是一个愚蠢的设计?
func2
和 func3
怎么样?它们是完全一样的东西吗?它们都是关于编译时间的吗?或者 func2
仍然是运行时?
如您所说,func
s 检查总是在运行时进行。
对于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 进行一些探索应该会告诉您您选择的编译器将做什么。
我对这三件事感到困惑。这是一个简单的例子:
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
是一个愚蠢的设计?
func2
和 func3
怎么样?它们是完全一样的东西吗?它们都是关于编译时间的吗?或者 func2
仍然是运行时?
如您所说,func
s 检查总是在运行时进行。
对于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 进行一些探索应该会告诉您您选择的编译器将做什么。