Доступ к объявлению использования внутри функтора: вопрос, связанный с областью действия - PullRequest
3 голосов
/ 15 мая 2019

Следующий фрагмент тестового кода не компилируется:

#include <iostream>
#include <string>
#include <iterator>
#include <functional>

using std::string;
using std::function;
using std::cout;
using std::endl;

void process (string);

int main (void){

    string s = "This string";

    process (s);

    return 0;
}

void process (string s){

    function<void(iter_t,iter_t)>print = [&] (iter_t start, iter_t finish){

        cout << *start << endl;
        cout << *finish << endl;

        return;
    };

    auto begin = s.begin();
    auto end = s.end() - 1;

    using iter_t = typeid(iterator_traits<begin>::iterator_category); 

    print(begin,end);

    return;
}

Я получаю ошибку компиляции:

code.cpp: In function void process(std::string):
code.cpp:24:16: error: iter_t was not declared in this scope
  function<void(iter_t,iter_t)>print = [&] (iter_t start, iter_t finish){

                ^~~~~~

Я ожидал, что псевдоним типа usingобъявление iter_t должно быть видно внутри функтора print(), так как сам функтор был определен в той же области видимости, что и объявление типа using.Очевидно, я что-то упустил.

Ответы [ 2 ]

1 голос
/ 15 мая 2019

Это не только using, это то, как работает язык.

Ваш using будет действителен только в области видимости блока, точнее с момента, когда существует объявление using, до конца области видимости блока.

Причина, по которой ваш код не работает, та же самая причина, по которой этот код не работает:

std::cout << foo;
int foo = 0;
1 голос
/ 15 мая 2019

Во-первых, ваше определение псевдонима не имеет смысла.То, что вы хотите, это тип итератора.Это должно быть

using iter_t = decltype(begin); 

Или

using iter_t = std::string::iterator;

Во-вторых, вы должны переместить это в начало функции, перед определением print.

Более того, я не могу понять вашу функцию print.Он печатает два отдельных символа.

Модифицированный код:

#include <iostream>
#include <string>
#include <iterator>
#include <functional>

using std::string;
using std::function;
using std::cout;
using std::endl;

void process (string);

int main (void){

    string s = "This string";

    process (s);

    return 0;
}

void process (string s){

    using iter_t = std::string::iterator;

    function<void(iter_t,iter_t)>print = [&] (iter_t start, iter_t finish){

        cout << *start << endl;
        cout << *finish << endl;

        return;
    };

    auto begin = s.begin();
    auto end = s.end() - 1;

    print(begin,end);

    return;
}

Это (правильно?) Выводит

T
g
...