2015-11-01 2 views
2
template <typename IN,typename OUT,bool isVector> 
OUT foo(IN x){ 
    if (isVector){ 
     return x[0];  
    } else { 
     return x; 
    } 
} 

После запроса this question Я ошибочно предположил, что приведенный выше код может быть скомпилирован, например.Как исправить этот шаблон:

foo<double,double,false>; 

, а также

foo<std::vector<double>,double,true>; 

Однако, даже если один из, если ветвей никогда не запускается на выполнение, то проверяется на корректность и, следовательно, выше не компилируется. Как я могу это исправить?

Код выше упрощенная, но я не знаю, как это исправить, так как шаблоны функций не могут иметь частичную специализацию ...

ответ

4

Вы можете «извлечь» параметры шаблона, которые вы хотите специализироваться на, сделать их параметры шаблона некоторой структуры, и написать функцию с остальными параметрами шаблона как статическая функция-члена:

template<bool IsVector = true> 
struct Bar { 
    template<typename In> 
    static auto foo(In input) { 
     return input[0]; 
    } 
}; 
template<> 
struct Bar<false> { 
    template<typename In> 
    static auto foo(In input) { 
     return input; 
    } 
}; 

Live example.

Очевидно, что это приводит к изменению на месте вызова, который йо и может «зацепиться», используя свободную функцию, вызывающего соответствующую функцию:

template<typename In, bool IsVector> 
auto real_foo(In input) { 
    return Bar<IsVector>::foo(input); 
} 

Структуры (Bar) затем обычно помещает внутри «хелперов» имен.


Другая возможность состоит в том, чтобы использовать теги и разрешение перегрузки:

template<typename In> 
auto foo(In input, std::true_type) { 
    return input[0]; 
} 
template<typename In> 
auto foo(In input, std::false_type) { 
    return input; 
} 
template<bool IsVector, typename In> 
auto foo(In input) { 
    using tag = typename conditional<IsVector, true_type, false_type>::type; 
    return foo(input, tag{}); 
} 

Live example.

Это использует std::conditional с std::true_type и std::false_type как различные типы, чтобы разрешение перегрузки найти подходящий foo функцию.

+0

выглядит хорошо, я попробую – user463035818

+0

Я предпочитаю первое решение, второе выглядит как C++ 11, которого я не могу использовать, к сожалению. Тем не менее, я не могу заставить его работать при вызове функции из шаблона 'A', а параметры шаблона, которые я передаю (' In' в вашем коде), являются параметрами шаблона 'A'. Любая идея, почему это может быть? Я попытаюсь сделать в MCVE ... – user463035818

+0

MCVE, который не компилирует: http://ideone.com/NQwfyA – user463035818

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