Вопрос по шаблону в C ++ - PullRequest
0 голосов
/ 06 июня 2011

Я знаю основы шаблонов в C ++, но я все еще изучаю это. У меня есть вопрос относительно следующего кода:

#include <iostream>

using namespace std;

class PNG {
public:
    static void draw() {
        cout<<"PNG drawing"<<endl;
    }
};

template <typename Image>
void draw() {
    Image::draw();
}


int main() {

    draw<PNG>();
}

функция draw(), я передаю ей тип Image, и она будет использовать draw() метод Image.

template <typename Image>
    void draw() {
        Image::draw();
    }

Здесь я передаю Image и хочу использовать метод draw() внутри Image, но функция шаблона draw() не имеет параметров. Итак, мой вопрос, если я вызову эту функцию шаблона draw() в main таким образом: draw<PNG>(); это разрешено? А как функция шаблона draw() знает, что PNG является классом, и как вызывается функция-член класса draw()?

Ответы [ 3 ]

4 голосов
/ 06 июня 2011

Ваш первый вопрос

если я вызову эту функцию шаблона draw () в главном таким образом: draw (); является это разрешено?

Как вы уже поняли, компилятор не может сам вывести , что вы имеете в виду draw<PNG>, если нет аргументов функции, из которых можно это выяснить.

Итак, вы должны написать (как вы уже делаете):

int main() {
   draw<PNG>();
}

Вы не можете опустить параметр шаблона здесь.

Ваш второй вопрос

и как шаблонная функция draw () знает, что PNG класс, и как функция-член класса draw () называется?

Когда шаблон функции (A) создается с параметром PNG, результирующее тело функции выглядит как (B):

// A:

template <typename Image>
void draw() {
    Image::draw();
}

// B:

    PNG::draw();

Анализатор знает, что для этого PNG должно быть пространством имен или классом / структурой. Если это не так, функция не будет компилироваться.

Скажем, вы набрали draw<int>(), например, вместо этого ваш код попытается вызвать int::draw(), что невозможно.

Теперь, благодаря SFINAE (посмотрите!), Вы не получите ошибку компиляции для прерванного вызова int::draw(); этот конкретный экземпляр будет просто запрещено существовать. Вероятно, вам скажут, что «функция не соответствует draw()», так как & mdash; дисконтирование запрещенных экземпляров & mdash; нет никакой возможной перегрузки функции draw, которую она может выбрать для использования.

3 голосов
/ 06 июня 2011
draw<PNG>();

PNG передается параметру шаблона Image.Итак, соответствующий шаблон создается компилятором.Другими словами, функция, сгенерированная с параметром шаблона Image, заменяемым параметром вызова PNG.

Поскольку PNG::draw() является статической функцией-членом, ей не требуется экземпляр для ее вызова.Итак,

Image::draw(); => PNG::draw() ; // Template parameter substituted and the call 
                                // is made.
0 голосов
/ 06 июня 2011

Вы не можете просто вызвать draw() в своей основной функции следующим образом:

draw();

Вам необходимо использовать его как функцию шаблона или функцию-член.

PNG dummy;
dummy.draw(); // Okay.
dummy::draw(); // Okay.
draw<PNG>(); // Okay.
draw(); // Not okay.

Я не уверен, что вы подразумеваете под своим вторым вопросом. Ключевое слово typename в данном случае означает, что функция будет принимать объект неизвестного типа, который, как оказалось, имеет член draw().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...