簡體   English   中英

模板參數無效時如何引發異常?

[英]How can I throw an exception when a template argument is invalid?

我有這段代碼,我試圖通過std::get獲得對元組的編譯時訪問。 當用戶輸入的元組中的數字超出范圍時,我想拋出一個異常。 不幸的是,我無法使它正常工作,所以如果代碼超出范圍,我使代碼返回數組中的第一個元素。

#include <tuple>

template <class... T>
struct input
{
    std::tuple<T...> var;
    input(T&&... t) : var(std::forward<T>(t)...) {}

    template <
          std::size_t N,
          bool in_range = 0 <= N && N < std::tuple_size<decltype(var)>::value
     >
    auto get()
          -> typename std::tuple_element<in_range ? N : 0, decltype(var)>::type&&
    {
        return std::move( std::get<in_range ? N : 0>(var) );
    }
};

template <class... Args>
void f(Args&&... args)
{
    auto arguments = input<Args...>(std::forward<Args>(args)...);

    arguments.template get<9>(); // returns 2 but I'd rather throw an exception
}

int main()
{
    f(2, 4, 6, 8);
}

如何拋出異常或至少使用static_assert技巧使此異常起作用?

當您在此處處理編譯時編程問題時,異常旨在報告運行時錯誤。

如果您介意不是非常透明的錯誤,編譯器會為您嘗試使用越界索引實例化tuple_element<>提供幫助,則可以使用SFINAE來防止在重載解析期間完全實例化您的函數:

template <class... T>
struct input
{
    std::tuple<T...> var;
    input(T&&... t) : var(std::forward<T>(t)...) {}

    template<std::size_t N,
        typename std::enable_if<(N < std::tuple_size<decltype(var)>::value)>::
            type* = nullptr>
    auto get() -> typename std::tuple_element<N, decltype(var)>::type&&
    {
        return std::move( std::get<N>(var) );
    }
};

如果您想添加一個更清晰的static_assert() ,則可以通過添加一個僅當N超出邊界時才選擇的重載來實現:

    template<std::size_t N,
        typename std::enable_if<(N >= std::tuple_size<decltype(var)>::value)>::
            type* = nullptr>
    void get()
    {
        static_assert(N < std::tuple_size<decltype(var)>::value, "OOB");
    }

這是一個生動的例子

嘗試這個:

template <class... Args>
void f(Args&&... args)
{
    static_assert(sizeof...(Args) > 9, "Invalid tuple size");

    auto arguments = input<Args...>(std::forward<Args>(args)...);

    arguments.template get<9>();
}

(拋出異常是沒有意義的,因為異常是針對* exception運行時流控制的,而不是針對靜態編譯錯誤檢查的。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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