首页 > 解决方案 > 如何在将模板转换为任意类型时避免编译器错误

问题描述

我正在尝试使用模板来读取任意std::vector类型的图像,如下所示:

#include <map>
#include <vector>
#include <string>

using namespace std;

class Reader
{
    public:
        static void readShorts(string path, vector<short>& buffer)
        {
            // read short buffer
        }

        static void readChars(string path, vector<char>& buffer)
        {
            // read char buffer
        }
};

template <typename T>
class GenericReader
{
    public:
        static void read(string path, T& buffer)
        {
            if (typeid(buffer) == typeid(vector<char>))
            {
                Reader::readChars(path, buffer);
            }
            else if (typeid(buffer) == typeid(vector<short>))
            {
                Reader::readShorts(path, buffer);
            }
        }
};

template <typename T>
class Container
{
    private:
        map<int, T> images;

    public:
        void readImage(string path, int imageId)
        {
            GenericReader<T>::read(path, images[imageId]);
        }
};

int main(int argc, char **argv)
{
    Container<vector<char>> container;
    container.readImage("some/path/img.tif", 0);
}

但我收到以下错误:

error C2664 : 'void Reader::readShorts(std::string,std::vector<short,std::allocator<_Ty>> &)' : cannot convert argument 2 from 'T' to 'std::vector<short,std::allocator<_Ty>> &'

我知道问题的发生是因为我创建了一个Container具有该类型的类的对象vector<char>,所以最终调用了 的readShorts成员函数Reader。但这不就是使用模板的目的吗?我在想在这种情况下我会得到一个运行时错误而不是编译器错误。

我的问题的第二部分是,有没有一种优雅的方式来做我想要在这里实现的目标?如果我做错了什么,我愿意接受不同的方法。

顺便说一句,我知道问题标题不是很清楚,所以请随时编辑它。

标签: c++templatescompiler-errors

解决方案


由于您GenericReader根本不是通用的(因为它仅适用于两种特定类型),并且只是委托给特定实现,因此更简单的方法是简单地使用重载:

void readVector(string path, vector<short>& buffer)
{
    // read short buffer
}

void readVector(string path, vector<char>& buffer)
{
    // read char buffer
}

接着:

void readImage(string path, int imageId)
{
    readVector(path, images[imageId]);
}

推荐阅读