簡體   English   中英

將用於類型檢查的 if constexpr 中的 static_assert 轉換為 C++14

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM