[英]Convert static_assert in if constexpr for type checking to C++14
我正在努力將 C++ 17 項目降級到 C++ 14。我找到了以下代碼:
#include <iostream>
#include <type_traits>
#include <typeinfo>
template <bool flag = false>
void get_assertion_message()
{
static_assert(flag, "unknown type");
}
template <typename T>
const char* get_name()
{
if constexpr (std::is_same<T, int>::value)
{
return "Integer";
}
else if constexpr (std::is_same<T, double>::value)
{
return "Double";
}
else
{
get_assertion_message();
return "Unknown";
}
}
int main()
{
std::cout << get_name<int>() << std::endl;
}
它使用if constexpr
檢查類型並相應地返回類型名稱。 如果沒有類型匹配,它會調用一個使用static_assert
的模板函數get_assertion_message
。
我正在考慮根據我之前的問題在這里應用解決方案: https ://stackoverflow.com/a/72300411/4688321。 該解決方案基於一種稱為“標簽調度”的方法。
但是,似乎由於static_assert
導致編譯失敗,並且無法按預期工作:
#include <iostream>
#include <type_traits>
#include <typeinfo>
template <bool flag = false>
void get_assertion_message()
{
static_assert(flag, "unknown type");
}
const char* get_name(std::integral_constant<int, 0>)
{
return "Integer";
}
const char* get_name(std::integral_constant<int, 1>)
{
return "Double";
}
const char* get_name(std::integral_constant<int, 2>)
{
get_assertion_message();
return "Unknown";
}
template<int N, class T, class... V>
struct dispatch_constant;
template<int N, class T>
struct dispatch_constant<N, T>
{
static constexpr int value = N;
};
template<int N, typename T, class U, class... V>
struct dispatch_constant<N, T, U, V...>
{
static constexpr int value = std::is_same<T, U>::value ? N - sizeof...(V) - 1 : dispatch_constant<N, T, V...>::value;
};
template <typename T>
const char* get_name()
{
using dispatch_t = std::integral_constant<int, dispatch_constant<2, T, int, double>::value >;
return get_name(dispatch_t{});
}
// template <typename T>
// const char* get_name()
// {
// if constexpr (std::is_same<T, int>::value)
// {
// return "Integer";
// }
// else if constexpr (std::is_same<T, double>::value)
// {
// return "Double";
// }
// else
// {
// get_assertion_message();
// return "Unknown";
// }
// }
int main()
{
std::cout << get_name<int>() << std::endl;
}
我在 C++ 14 中使用 GCC 5.4 進行編譯。是否可以更改上述“標簽調度”解決方案,使其不會因static_assert
而失敗? 請提供建議。
您可以拆分函數模板並進行專門化:
template <typename T, bool flag = false>
const char* get_name() {
static_assert(flag, "unknown type");
return nullptr;
}
template <>
const char* get_name<int>() {
return "Integer";
}
template <>
const char* get_name<double>() {
return "Double";
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.