Как я могу записать шаблон функции для всех типов с конкретной чертой типа?

Рассмотрите следующий пример:

struct Scanner
{
    template <typename T>
    T get();
};

template <>
string Scanner::get()
{
    return string("string");
}

template <>
int Scanner::get()
{
    return 10;
}

int main()
{
    Scanner scanner;
    string s = scanner.get<string>();
    int i = scanner.get<int>();
}

Scanner класс используется для извлечения маркеров из некоторого источника. Вышеупомянутый код хорошо работает, но перестал работать, когда я пытаюсь get другие целочисленные типы как a char или unsigned int. Код для чтения этих типов является точно тем же как кодом для чтения int. Я мог просто копировать код для всех других целочисленных типов, которые я хотел бы считать, но я скорее определю один шаблон функции для всех целочисленных типов.

Я попробовал следующее:

struct Scanner
{
    template <typename T>
    typename enable_if<boost::is_integral<T>, T>::type get();
};

Который работает как очарование, но я не уверен, как добраться Scanner::get<string>() функционировать снова. Так, как я могу написать код так, чтобы я мог сделать scanner.get<string>() и scanner.get<any integral type>() и имеет единственное определение для чтения всех целочисленных типов?

Обновление: вопрос о премии: Что, если я хочу принять больше чем один диапазон классов на основе некоторых черт? Например: как я должен приблизиться к этой проблеме, если я хочу иметь три get функции, которые принимают (i) целочисленные типы (ii) типы с плавающей точкой (iii) строки, соответственно.

7
задан TC. 29 March 2010 в 11:08
поделиться

2 ответа

struct Scanner
{
    template <typename T>
    typename boost::enable_if<boost::is_integral<T>, T>::type get()
    {
        return 10;
    }
    template <typename T>
    typename boost::disable_if<boost::is_integral<T>, std::string>::type get()
    {
        return "string";
    }
};

Обновление «Что, если я хочу принять более одного диапазона классов на основе некоторых характеристик?»

struct Scanner
{
    template <typename T>
    typename boost::enable_if<boost::is_integral<T>, T>::type get()
    {
        return 10;
    }

    template <typename T>
    typename boost::enable_if<boost::is_floating_point<T>, T>::type get()
    {
        return 11.5;
    }

    template <typename T>
    std::string get(
          typename boost::disable_if<boost::is_floating_point<T>, T>::type* = 0, 
          typename boost::disable_if<boost::is_integral<T>, T>::type* = 0)

    {
        return std::string("string");
    }
};
10
ответ дан 6 December 2019 в 19:35
поделиться

Перейти к другому шаблону. Вот общий шаблон того, что вы хотите:

template <typename T, bool HasTrait = false>
struct scanner_impl;

template <typename T>
struct scanner_impl
{
    // Implement as though the trait is false
};

template <typename T>
struct scanner_impl<true>
{
    // Implement as though the trait is true
};

// This is the one the user uses
template <typename T>
struct scanner : scanner_impl<T, typename has_my_trait<T>::value>
{
};
3
ответ дан 6 December 2019 в 19:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: