Синтаксис для шаблонных функций-членов - PullRequest
3 голосов
/ 19 января 2011

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

template <typename Datatype>
class MyClass
{
    void doStuff();

    template <typename AnotherDatatype>
    void doTemplateStuff(AnotherDatatype Argument);
};

template <typename Datatype>
void MyClass<Datatype>::doStuff()
{
    // ...
}

template <typename Datatype>
template <typename AnotherDatatype>
void MyClass<Datatype>::doTemplateStuff(AnotherDatatype Argument)
{
    // ...
}

Реализация для второй функции-члена, doTemplateStuff, не будет компилироваться, если я сгущу ее так:

template <typename Datatype, typename AnotherDatatype>
void MyClass<Datatype>::doTemplateStuff(AnotherDatatype Argument)
{
    // ...
}

Почемуэтот?Разве разделение информации о шаблоне запятыми не должно иметь такой же эффект, как размещение каждого typename в отдельной строке?Или есть какая-то тонкая разница, о которой я не знаю ...?

(Кроме того, если кто-то может придумать лучший заголовок, пожалуйста, дайте мне знать.)

Ответы [ 2 ]

3 голосов
/ 19 января 2011

Это отличный вопрос.Я не знаю конкретной причины, по которой комитет по стандартам решил разработать шаблоны таким образом, но я думаю, что это обратный вызов лямбда-исчисления и теории типов.С математической точки зрения существует изоморфизм между любой функцией, которая принимает два аргумента и возвращает значение, и функцией, которая принимает один аргумент, затем возвращает функцию, которая принимает еще один аргумент, а затем возвращает значение.Например:

λx.λy.x + y

изоморфен (но не идентичен)

λ (x, y).x + y

где (x, y) - один объект, представляющий пару x и y.

С помощью шаблонов функций-членов C ++ C ++ решил использовать первую из этих систем.Вы должны указать все аргументы для самой внешней функции, а затем отдельно все аргументы для самой внутренней функции.Математически это эквивалентно одновременному указанию всех аргументов в одном списке аргументов, но C ++ не решил этого делать.

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

2 голосов
/ 19 января 2011

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

Следовательно,

template<typename T, typename V>
struct Foo{
    void bar();
};

template<typename T, typename V>
void Foo<T,V>::bar(){...}

- это то, что он ожидает увидеть.

template<typename T>
struct Foo{
    void bar();
}

template<typename T, typename V>
void Foo<T>::bar(){...}

- ошибка.Интересно, откуда появился этот другой параметр шаблона.

Если вы хотите сделать это, вам нужно написать функцию прямо здесь:

template<typename T>
struct Foo{
    template<typename V>
    void bar(const V& _anInputValue){
        cout << _anInputValue;
    }

    void baz();
};

template<typename T>
void Foo<T>::baz(){
    cout << "Another function.";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...