I am trying to implement a "compare" function. Depends on the input argument, the compare targets can be one of the 2 classes. That is why I am thinking to use template for easier code maintenance. I am new to template, can't figure out what is going on.
class Compare_Output
{
public:
static Directory* empty_dir;
static File* empty_file;
enum COMPARE_TYPE { FILE, SUB_DIR };
Directory* dir1;
Directory* dir2;
int level;
std::pair<std::string,std::string> dir_name;
std::vector<Compare_Output> sub_dir_compare;
std::vector<File_Compare_Result> list;
Compare_Output(Directory* dir1, Directory* dir2, int level);
template<class T>
void compare(int type, int level);
Compare_Output& operator=(const Compare_Output&) = default;
};
class Directory
{
public:
fs::path path;
Directory* parent;
std::vector<Directory*> sub_dir;
std::vector<File*> files;
Directory(const fs::path path, Directory* parent = NULL);
Directory& operator=(const Directory&) = default;
std::string getDirName(void);
static void compare(Directory& dir1, Directory& dir2, std::vector<Compare_Result> &result);
static void getAllFiles(Directory& dir, std::vector<std::pair<File*, int>>& result, int level, bool include_dir); // use for root directory only, thus make it static
};
template<class T>
void Compare_Output::compare(int type, int level)
{
int i = 0, j = 0;
std::vector<T*> t1, t2;
if (type == FILE)
{
t1 = dir1->files;
t2 = dir2->files;
}
else if (type == SUB_DIR)
{
t1 = dir1->sub_dir;
t2 = dir2->sub_dir;
}
while (!(i == t1.size() && j == t2.size()))
{
// avoid the out of bound error
if (i == t1.size() && i != 0)
i--;
if (j == t2.size() && j != 0)
j--;
T* item1 = t1.at(i);
T* item2 = t2.at(j);
if (*item1 == *item2)
{
list.push_back({ true, item1, item2 });
i++;
j++;
}
}
}
Templates don't work the way you think they do. To have the interface you want, you need two functions (the helper can be private
if you want), like this:
template<class T>
void Compare_Output::compare_helper(std::vector<T*> t1, std::vector<T*> t2, int level)
{
int i = 0, j = 0;
while (!(i == t1.size() && j == t2.size()))
{
// avoid the out of bound error
if (i == t1.size() && i != 0)
i--;
if (j == t2.size() && j != 0)
j--;
T* item1 = t1.at(i);
T* item2 = t2.at(j);
if (*item1 == *item2)
{
list.push_back({ true, item1, item2 });
i++;
j++;
}
}
}
void Compare_Output::compare(int type, int level)
{
if (type == FILE)
{
compare_helper(dir1->files, dir2->files, level);
}
else if (type == SUB_DIR)
{
compare_helper(dir1->sub_dir, dir2->sub_dir, level);
}
}
The reason your approach didn't work is that type
is only known at runtime, but T
needs to be set at compile time, so t1
and t2
can't have the right types if you declare them where you did.
Note that there's other things about your code that still look wrong to me. This is just enough to fix the compiler error that your question is about.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.