Как избежать спецификации шаблона при вызове функции - PullRequest
1 голос
/ 03 декабря 2011

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

У меня есть шаблонная структура

template<typename T>
struct telement {
    typedef {
        T element;
        float some_value;
    } type;
};

telement<float>::type theElement;

и у меня есть функция:

template<typename T>
float do_some_stuff( const typename telement<T>::type& x) {
    // ...
}

К сожалению, g ++ жалуется, когда я звоню

do_some_stuff( theElement );

и я должен позвонить:

do_some_stuff<float>( theElement );

Можно ли избежать спецификации шаблона при каждом вызове функции? Я думал, что компилятор должен выяснить тип автоматически ...

Ответы [ 2 ]

4 голосов
/ 03 декабря 2011

Это один из не выводимых контекстов. Аргумент шаблона T не может быть выведен компилятором.

Задайте этот вопрос себе: когда вы пишете это,

do_some_stuff( theElement );

какой тип аргумента, по вашему мнению, должен быть вычтен из T?

Вы, наверное, думаете T=float? Ну, это только одна возможность. Там может существовать специализация для шаблона класса:

//the compiler cannot assume that such specialization doesn't exist!
template<>
struct telement<someType>
{
    typedef {
        float element;
        float some_value;
    } type;
};

Тогда даже в этом случае вложенный тип telement<someType>::type совпадает с telement<float>::type. Вы видите двусмысленность? Не существует единой связи между T и вложенным type. На самом деле может быть много-одно отношение. Может быть много T, для которых вложенный тип будет таким же, идентичным.

Итак, учитывая вложенный тип, как компилятор может определить аргумент шаблона? Не может

В SO уже есть несколько тем, объясняющих подобные ситуации, см. Эти:


Решение состоит в том, чтобы просто написать шаблон функции как:

template<typename T>
float do_some_stuff( const T& x) {
    // ...
}

В конце концов, какой смысл писать telement<T>::type в параметре?

2 голосов
/ 03 декабря 2011

Вот способ работы с ним:

#include <iostream>


template<typename T>
struct telement {
    typedef struct {
        typedef T t_element_type;
        typedef float t_value_type;

        t_element_type element;
        t_value_type some_value;
    } type;
};


template<typename T>
float imp_do_some_stuff(const typename telement<T>::type& x) {
    return x.some_value;
}

template<typename T>
float do_some_stuff(const T& x) {
    return imp_do_some_stuff<typename T::t_element_type>(x);
}

int main() {
    telement<float>::type theElement;

    do_some_stuff(theElement);
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...