簡體   English   中英

具有float類型的模板實例化的位移編譯錯誤

[英]Bit shift compile error from template instantiation with float type

我有一個模板化的函數,可以在浮點數或(無符號)整數類型上運行,如下所示:

template< typename T >
void typedFunc( T& data )
{
    // .... lots of code ....

    if( std::numeric_limits<T>::is_integer )
    {
        data = data << 8;
        // .... do some processing ....
    }
    else
    {
        // .... do some slightly different processing ....
    }

    // .... lots more code ....
}

當我將該函數用於浮點類型時,我從位移獲得編譯錯誤,因為您無法對浮點進行位移。 對於一個浮點數,這段代碼永遠不會執行,並且(希望)被優化掉,所以只需要編譯。 我可以通過將data轉換為int來擺脫編譯錯誤,但是當與整數類型一起使用時,它會改變函數的行為。

如何在不改變其行為的情況下編譯此代碼?

TIA

您可以拆分方法並專門化非常見部分:

template< typename T >
void preTypedFunc( T& data )
{
    // .... lots of code ....
}

template< typename T >
std::enable_if_t<std::numeric_limits<T>::is_integer>
midTypedFunc( T& data )
{
    data = data << 8;
    // .... do some processing ....
}

template< typename T >
std::enable_if_t<!std::numeric_limits<T>::is_integer>
midTypedFunc( T& data )
{
    // .... do some slightly different processing ....
}

template< typename T >
void postTypedFunc( T& data )
{
    // .... lots more code ....
}

template< typename T >
void typedFunc( T& data )
{
    preTypedFunc(data);
    midTypedFunc(data);
    postTypedFunc(data);
}

模板函數的整個主體需要對給定的參數集有效,即使某些類型的某些代碼永遠不會被執行。

解決此問題的一種簡單方法是將特定於類型的處理分離為單獨的函數和標記分派以從中進行選擇:

template <typename T>
void doProcessing (std::true_type, T& data);

template <typename T>
void doProcessing (std::false_type, T& data);

//usage
doProcessing (std::is_integral<T>{}, data);

您應該使用標簽分派拆分不兼容的代碼,如下所示:

template<typename T>
void doShift(T& data, std::false_type)
{ data = data << 8; }

template<typename T>
void doShift(T& data, std::true_type)
{ /* do something with float */ }

template< typename T >
void typedFunc( T& data )
{
     // .... lots of code ....
     doShift(data, typename std::is_floating_point<T>::type{});
     // .... lots more code ....
}

暫無
暫無

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

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