0

在下面的代码中,我必须将 boolean_cast 转换为 Tdestination 以避免编译器警告(从 'VARIANT_BOOL' 到 'bool' 的截断)。这是编译器问题还是 C++ 问题?

template<typename TDestination, typename TSource>
TDestination boolean_cast(TSource source)
{
    TDestination destination;

    static_assert(std::is_same<TDestination, bool>::value || std::is_same<TDestination, VARIANT_BOOL>::value, "destination must be bool or VARIANT_BOOL");

    //convert to bool
    if (std::is_same<TDestination, bool>::value)
    {
        if (source)
            destination = true;
        else
            destination = false;
    }
    //convert to VARIANT_BOOL
    else
    {
        if (source)
            destination = (TDestination)VARIANT_TRUE;
        else
            destination = (TDestination)VARIANT_FALSE;
    }

    return destination;
}
4

1 回答 1

0

正如@nm 在评论中所说,编译器不会停止编译 的错误分支,因此当目标类型为和目标类型为 时if,两个分支都必须是有效代码。boolVARIANT_BOOL

您可以通过分派到部分专门针对目标类型的帮助模板来避免该问题,例如

template<typename TDestination, typename TSource>
struct boolean_cast_impl;  // undefined

template<typename TSource>
struct boolean_cast_impl<bool, TSource>
{
    static bool cast(TSource source)
    {
        return source ? true : false;
    }
};

template<typename TSource>
struct boolean_cast_impl<VARIANT_BOOL, TSource>
{
    static VARIANT_BOOL cast(TSource source)
    {
       return source ? VARIANT_TRUE : VARIANT_FALSE;
    }
};

template<typename TDestination, typename TSource>
TDestination boolean_cast(TSource source)
{
    static_assert(std::is_same<TDestination, bool>::value || std::is_same<TDestination, VARIANT_BOOL>::value, "destination must be bool or VARIANT_BOOL");

    return boolean_cast_impl<TDestination, TSource>::cast(source);
}

甚至只是在特化中定义正确类型的常量:

template<typename TDestination, typename TSource>
struct boolean_cast_values;  // undefined

template<typename TSource>
struct boolean_cast_values<bool, TSource>
{
    static const bool true_ = true;
    static const bool false_ = false;
};

template<typename TSource>
struct boolean_cast_values<VARIANT_BOOL, TSource>
{
    static const VARIANT_BOOL true_ = VARIANT_TRUE;
    static const VARIANT_BOOL false_ = VARIANT_FALSE;
};

template<typename TDestination, typename TSource>
TDestination boolean_cast(TSource source)
{
    static_assert(std::is_same<TDestination, bool>::value || std::is_same<TDestination, VARIANT_BOOL>::value, "destination must be bool or VARIANT_BOOL");

    typedef boolean_cast_values<TDestination, TSource> values;
    return source ? values::true_ : values::false_;
}
于 2013-07-30T10:55:05.997 回答