Специализированный шаблон для любого вектора <any_arithmetic_data_type> - PullRequest
3 голосов
/ 29 сентября 2011

У меня есть шаблонный метод с двумя специализированными версиями для типа bool и vector<string>.

Базовая версия:

template <class T> 
const T InternGetValue(const std::string& pfad) const
{
  ...   
}

Специализированные версии:

template <>
const bool InternGetValue(const std::string& pfad) const
{
  ...
}  

template <>
const std::vector<std::string> InternGetValue< std::vector<std::string>>(const std::string& pfad) const
{
...
}

Теперь я хотел бы реализовать специализацию one , которая будет принимать все типы vector<aritmethic_data_type>, такие как vector<double> vector<int> или vector<float>.

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

Это то, что я пробовал до сих пор (приводит к ошибке «незаконно»использование явных аргументов шаблона '):

template <class T>
const std::vector<T> InternGetValue< std::vector<T>>(const std::string& pfad, typename boost::enable_if<boost::is_arithmetic<T>>::type* dummy = 0) const
{
}

Ответы [ 2 ]

8 голосов
/ 29 сентября 2011

Я думаю, std::enable_if и std::is_integral вместе могут решить эту проблему:

template<typename T>
std::vector<typename std::enable_if<std::is_integral<T>::value, T>::type> 
f(const std::string& d);

Если у std:: их нет, тогда используйте boost::, если можете.У них есть они.

5 голосов
/ 29 сентября 2011

ОК, Uber сложный, но у меня все работает.Я не мог просто проверить is_integral на типе value_type внутри первой (по умолчанию) перегрузки функции, поскольку это заставило бы SFINAE удалить перегрузку для не-векторов.

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

Это работает на VS2010.

#include <vector>
#include <string>
#include <type_traits>

using namespace std;

template <typename T> struct is_vector { static const bool value = false; };
template <typename T> struct is_vector< std::vector<T> > { static const bool value = true; };

// metafunction to extract what type a vector is specialised on
// vector_type<vector<T>>::type == T
template <class T>
struct vector_type
{
private:
    template <class T>
    struct ident
    {
        typedef T type;
    };

    template <class C> 
    static ident<C> test(vector<C>);

    static ident<void> test(...);

    typedef decltype(test(T())) vec_type;
public:
    typedef typename vec_type::type type;
};

// default version
template <class T>
const typename enable_if<!is_vector<T>::value || !is_integral<typename vector_type<T>::type>::value, T>::type
InternGetValue(const std::string& pfad)
{
    return T();
}

// bool specialisation
template <>
const bool
InternGetValue<bool>(const std::string& pfad)
{
    return true;
}

// vector<string> specialisation
template <>
const vector<string>
InternGetValue<vector<string>>(const std::string& pfad)
{
    return vector<string>();
}

// vector<T> specialisation (where T is integral)
template <class T>
const typename enable_if<is_vector<T>::value && is_integral<typename vector_type<T>::type>::value, T>::type
InternGetValue(const std::string& pfad)
{
    return T();
}

int main()
{
    string x;
    auto a = InternGetValue<int>(x);
    auto b = InternGetValue<bool>(x);
    auto c = InternGetValue<vector<string>>(x);
    auto d = InternGetValue<vector<pair<int, int>>>(x);
    auto e = InternGetValue<vector<int>>(x);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...