无法编译C ++函数

时间:2015-06-30 09:22:25

标签: c++

我的问题可能是一个小问题,但作为一个初学者,我想学习细节,因此会感谢任何指出我的错误的人。

在我的头文件中,我定义了一个像这样的函数

void  GetFileNames(const fs::path&, const string&, vector<fs::path>&, const bool);

然后函数定义在GetFileNames.cpp中如下所示:

void GetFileNames(const fs::path& root, const string& ext, vector<fs::path>& names, const bool recursiveflag)
{
        if(!fs::exists(root) || !fs::is_directory(root))
        {
                cout<<"The root path either does not exist, or is not a valid folder.\n"<<endl;
                return;
        }

    if (recursiveflag)
    {
            fs::recursive_directory_iterator it(root);
            fs::recursive_directory_iterator endit;
    }
    else
    {
            fs::directory_iterator it(root);
            fs::directory_iterator endit;
    }

    while(it != endit)
    {
            if(fs::is_regular_file(*it) && it->path().extension() == ext)
                    names.push_back(it->path().filename());

            ++it;
    }
}

然后我尝试编译程序test.cpp,其中函数已按以下方式调用:

int main(int argc, char** argv)
{
        vector<fs::path> names;
        fs::path root(argv[1]);
        string ext(argv[2]);
        GetFileNames(root,ext,names,true);
        for(auto i = names.begin(); i!= names.end(); ++i)
                cout<< (*i).string()<<endl;
        return 0;
}

我收到以下错误:

Scanning dependencies of target Test
[ 33%] Building CXX object src/CMakeFiles/Test.dir/test.cpp.o
[ 66%] Building CXX object src/CMakeFiles/Test.dir/GetFileNames.cpp.o
/Users/ujjwalujjwal/prog/src/GetFileNames.cpp:22:8: error: use of undeclared identifier 'it'
        while(it != endit)
              ^
/Users/ujjwalujjwal/prog/src/GetFileNames.cpp:22:14: error: use of undeclared identifier 'endit'
        while(it != endit)
                    ^
/Users/ujjwalujjwal/prog/src/GetFileNames.cpp:24:27: error: use of undeclared identifier 'it'
                if(fs::is_regular_file(*it) && it->path().extension() == ext)
                                        ^
/Users/ujjwalujjwal/prog/src/GetFileNames.cpp:24:34: error: use of undeclared identifier 'it'
                if(fs::is_regular_file(*it) && it->path().extension() == ext)
                                               ^
/Users/ujjwalujjwal/prog/src/GetFileNames.cpp:25:20: error: use of undeclared identifier 'it'
                        names.push_back(it->path().filename());
                                        ^
/Users/ujjwalujjwal/prog/src/GetFileNames.cpp:27:5: error: use of undeclared identifier 'it'
                ++it;
                  ^
6 errors generated.
make[2]: *** [src/CMakeFiles/Test.dir/GetFileNames.cpp.o] Error 1
make[1]: *** [src/CMakeFiles/Test.dir/all] Error 2
make: *** [all] Error 2

我似乎不明白我究竟在哪里犯了一个概念错误。这看起来非常简单,但我想了解这里发生的事情。

3 个答案:

答案 0 :(得分:3)

您正在之前的if-else作用域中定义迭代器

fs::recursive_directory_iterator it(root);
fs::recursive_directory_iterator endit;

因此,当您稍后在while循环中引用它们时,它们不再存在,因为一旦if-else块完成,变量就会被销毁。

由于根据bool参数有不同类型的迭代器,您可能必须在每个ifelse块中实际放置while循环以确保执行while循环时,迭代器仍然存在。

但是你选择继续它与函数的boolean参数无关 - 注意编译器错误,因为它们告诉你什么是错误的。

答案 1 :(得分:1)

it在另一个块中定义,你不能在你的while循环中使用它,除非你在之前定义它

答案 2 :(得分:0)

问题在于这段代码......

    ....
    while(it != endit)
    {
        if(fs::is_regular_file(*it) && it->path().extension() == ext)
                names.push_back(it->path().filename());

        ++it;
    }
    ....

...正在使用两个变量,'it'和'endit'。但是,在这两种情况下,您声明这些都在{}块内。这使得声明仅对这些块是本地的。

每个'it'和'endit'的声明属于不同类型,你的问题会稍微恶化。

你可以将声明移到局部块之外并使它们成为一些常见类型(在本例中为InputIterators),或者你可以在这两个局部块内的末尾移动while循环......

...
    if (recursiveflag)
    {
        fs::recursive_directory_iterator it(root);
        fs::recursive_directory_iterator endit;

        while(it != endit)
        {
            if(fs::is_regular_file(*it) && it->path().extension() == ext)
                    names.push_back(it->path().filename());

            ++it;
        }
    }
    else
    {
        fs::directory_iterator it(root);
        fs::directory_iterator endit;

        while(it != endit)
        {
            if(fs::is_regular_file(*it) && it->path().extension() == ext)
                    names.push_back(it->path().filename());

            ++it;
        }
    }
...

虽然这会导致不必要的代码重复,并进一步导致维护噩梦。