Когда мне нужно объявить функцию, используемую в шаблоне? - PullRequest
2 голосов
/ 05 июля 2010

У меня (наверное) простой вопрос.Когда мне нужно объявить функцию, используемую в шаблоне?Следующий код распечатывает (используя gcc> = 4.1):

init my A A

no init

При использовании gcc 4.0 печатается следующий кодout:

init my A object

init my string object

#include <iostream>
#include <string>

template<typename T>
void init(T& t){
        std::cout << "no init" << std::endl;
}

// void init(std::string& t);

template <typename T>
void doSomething(T& t){
        init(t);
        // do some further stuff
}

void init(std::string& t){
        std::cout << "init my string object" << std::endl;
}


class A{

};

void init(A& t){
        std::cout << "init my A object" << std::endl;
}

int main(){
        A a;
        doSomething(a);
        std::string s("test");
        doSomething(s);
        return 0;
}

В чем разница между использованием std :: string иA?Разве не должно быть такого же поведения?

С дополнительным предварительным объявлением оно работает нормально, но когда оно мне нужно?

Cheers, CSpille

1 Ответ

4 голосов
/ 05 июля 2010

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

Таким образом, для std::string виден и вызывается только общий шаблон функции init, поскольку в пространстве имен std его нет.Для A более конкретная функция находится в глобальном пространстве имен A.

Если вы передадите объявление функции, специфичной для строки, до doSomething, обычный неквалифицированный поиск найдет ее в определении и использует позже.

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

template <typename T>
void doSomething(T& t){
    (init)(t);
    // won't do ADL
}

(В качестве побочного узла: в этом случае не только поиск, зависящий от аргумента, запрещается при создании экземпляра, но init не будет во-первых зависимым именем - только без скобоки неквалифицированные имена функций становятся зависимыми. Таким образом, в любом случае выполняется только поиск не-ADL определения, и вообще не выполняется поиск экземпляров, даже если бы там была форма, отличная от ADL, которая была бы там сделана.)

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