在没有调用

时间:2017-12-03 20:40:58

标签: c++

我有以下代码:

inline uint16_t byteSwap(uint16_t i) {/*..*/}
inline uint32_t byteSwap(uint32_t i) {/*..*/}

template<typename T>
T byteSwapLe(T i)
{
    #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    return i;
    #else
    return byteSwap(i);
    #endif
}

byteSwapLe()的问题在于它接受小端机器上的任何类型而不是给出模糊的调用错误。

我需要一种方法来确保变量与byteSwap()重载兼容,即使没有实际调用(在little-endian机器上), 从而迫使用户在必要时使用显式演员。

我可以使用decltype()技巧:

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
return (decltype(byteSwap(i)))i;

但也许有一个不那么强硬的解决方案适用于pre-c ++ 11编译器,并且不需要很多样板代码?

更新另一个简单的解决方法是拨打电话,但是 将结果转换为void,因此编译器将能够将其删除:

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
(void)byteSwap(i);
return i;

这适用于前C ++ 11编译器。

1 个答案:

答案 0 :(得分:0)

您可以使用SFINAE选择某个过载。但是,这需要C ++ 11,如果没有可用的重载,则错误消息为meh。

// To trigger this example, remove in production!
#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__

#include <cstdint>
#include <iostream>
#include <type_traits>

template < typename T >
inline typename std::enable_if<std::is_same<T,uint16_t>::value,T>::type
byteSwap(T i) {
    std::cout << "uint16_t\n";
    return i;
}

template < typename T >
inline typename std::enable_if<std::is_same<T,uint32_t>::value,T>::type
byteSwap(T i) {
    std::cout << "uint32_t\n";
    return i;
}

template<typename T>
T byteSwapLe(T i)
{
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    return i;
#else
    return byteSwap(i);
#endif
}

int main()
{
    uint16_t a = 1;
    byteSwapLe(a);

    uint32_t b = 2;
    byteSwapLe(b);

    int c = 3;
    //byteSwapLe(c); // BOOM!
}

Live example