简体   繁体   中英

C++ Template - no matching overloaded function found, could not deduce template argument for 'T'

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM