Search code examples
c++scopeusingfunctor

Accessing a using declaration within a functor: a scope related question


The following piece of test code doesn't compile:

#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;
}

The compilation error that I get is:

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){

                ^~~~~~

I was expecting that the using type alias declaration iter_t should be visible within the functor print(), as the functor itself has been defined within the same scope as the using type declaration. Obviously, I am missing something.


Solution

  • First, your alias definition does not make sense. What you want is the type of the iterator. It should be

    using iter_t = decltype(begin); 
    

    Or

    using iter_t = std::string::iterator;
    

    Second, you have to move this to the beginning of the function, before the definition of print.

    Moreover, I can't understand your print function. It prints two separate characters.

    Modified code:

    #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;
    }
    

    This (correctly?) outputs

    T
    g