std::is_same 不使用 bool
std::is_same not working with bool
#include <array>
template<typename T>
void Func(T Param)
{
int Val = 0;
if (std::is_same<T, bool>::value)
Val += Param ? 1 : 0;
}
int main()
{
std::array<int, 10> A;
Func(A);
return 0;
}
当我用 gcc 或 MSVC 编译时,我得到:
Error C2440 '?': cannot convert from 'std::array<int,10>' to 'bool'
编译器甚至不应该编译 Val += Param ? 1 : 0;
因为 std::is_same<std::array<int, 10>, bool>::value
是 0 吗?
在您当前的场景中,当编译器尝试实例化 Func
模板时,
它看到:
Val += Param ? 1 : 0;
其中 Param
的类型为 std::array<int, 10>
,因此它会抱怨。
问题在于带有 std::is_same
的 if 子句在函数模板实例化期间不会神奇地删除部分代码。
因为 C++17 你可以使用 if constexpr
:
if constexpr (std::is_same_v<T, bool>)
Val += Param ? 1 : 0;
}
在 C++17 之前,你可以做一些标签调度的实验。例如,类似的东西应该有效:
template<typename T>
auto get(const T& p, std::true_type) {
return p ? 1 : 0;
}
template<typename T>
auto get(const T& p, std::false_type) {
return 0;
}
然后:
template<typename T>
void Func(T Param)
{
int Val = 0;
// ...
Val += get(Param, std::is_same<T, bool>{});
}
#include <array>
template<typename T>
void Func(T Param)
{
int Val = 0;
if (std::is_same<T, bool>::value)
Val += Param ? 1 : 0;
}
int main()
{
std::array<int, 10> A;
Func(A);
return 0;
}
当我用 gcc 或 MSVC 编译时,我得到:
Error C2440 '?': cannot convert from 'std::array<int,10>' to 'bool'
编译器甚至不应该编译 Val += Param ? 1 : 0;
因为 std::is_same<std::array<int, 10>, bool>::value
是 0 吗?
在您当前的场景中,当编译器尝试实例化 Func
模板时,
它看到:
Val += Param ? 1 : 0;
其中 Param
的类型为 std::array<int, 10>
,因此它会抱怨。
问题在于带有 std::is_same
的 if 子句在函数模板实例化期间不会神奇地删除部分代码。
因为 C++17 你可以使用 if constexpr
:
if constexpr (std::is_same_v<T, bool>)
Val += Param ? 1 : 0;
}
在 C++17 之前,你可以做一些标签调度的实验。例如,类似的东西应该有效:
template<typename T>
auto get(const T& p, std::true_type) {
return p ? 1 : 0;
}
template<typename T>
auto get(const T& p, std::false_type) {
return 0;
}
然后:
template<typename T>
void Func(T Param)
{
int Val = 0;
// ...
Val += get(Param, std::is_same<T, bool>{});
}