2013-07-30 4 views
0

В приведенном ниже коде я должен указать для TDestination для boolean_cast, чтобы избежать предупреждения компилятора (усечение от '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; 
} 
+0

почему вы используете VARIANT_ в первую очередь? –

+3

Это не так. Тип является одним и тем же типом в обеих ветвях оператора 'if', даже если он окружен шаблоном mumbo-jumbo. Если ваш 'TDestination' является' bool', это 'bool' внутри ветви' else' тоже, хотя его код не выполняется. –

ответ

0

As @ n.m. сказано в комментарии, компилятор не прекращает компиляцию ложной ветви if, поэтому оба ветви должны быть действительными, когда тип назначения - bool, а когда тип назначения - VARIANT_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_; 
} 
+0

KH: Я использую VARIANT_BOOL, потому что это требуется внешним COM-интерфейсом JW: Спасибо за решения – Rocinante8

Смежные вопросы