C ++-在模板类

时间:2019-04-16 17:40:04

标签: c++ templates

我有这两节课:

template <typename GeomType>
class InputCSV
{
public:
    InputCSV(DataSet<GeomType> * ds) : ds(ds) {}
    virtual ~InputLoaderCSV() = default;

    DataSet<GeomType> * ds;
};

template <typename GeomType>
struct DataSet
{
    template <typename LoaderType>
    static DataSet<GeomType> Create()
    {
        DataSet<GeomType> ds;
        ds.fileName = "something";
        ds.input = std::make_shared<LoaderType<GeomType>>(&ds);
        return std::move(ds);
    };

    DataSet(const DataSet & ds) = delete;

    DataSet(DataSet && ds)
    {
        this->fileName = std::move(ds.fileName);
        this->input = std::move(ds.input);
        this->input->ds = this;

        ds.input = nullptr;     
    }

    std::string fileName;
    std::shared_ptr<InputLoader<GeomType>> input;

   protected:   
        DataSet() : input(nullptr) {}
}

现在在代码中的某个地方,我想做

auto ds = DataSet<Line>::Create<InputCSV>();

其中Line是我拥有的一些结构。但是,这不起作用,并且出现此错误:

error C2672: 'DataSet<Line>::Create': no matching overloaded function found
error C3206: 'DataSet<Line>::Create': invalid template argument for 'LoaderType', missing template argument list on class template 'InputLoaderCSV'
note: see declaration of 'DataSet<Line>::Create' 
error cannot access protected member declared in class 'DataSet<Line>'
note: see declaration of 'DataSet<Line>::DataSet' note: see declaration of 'DataSet<Line>'

是否有解决方案来拥有这种“语法”,或者我必须写

auto ds = DataSet<Line>::Create<InputCSV<Line>>();

并更改

ds.input = std::make_shared<LoaderType<GeomType>>(&ds);

ds.input = std::make_shared<LoaderType>(&ds);

在此示例中,我不喜欢InputCSV中的“重复项”,因为没有其他内容了。

1 个答案:

答案 0 :(得分:3)

您要寻找的是template template parameter。由于InputCSV是模板类型,因此必须指定其模板参数。如果将Create更改为使用模板模板参数,则可以将模板传递给Create并像使用其他模板一样使用它。为此,您需要使用

template <template<typename> typename LoaderType>
// pre C++17 you have to use template <template<class> class LoaderType> instead
static DataSet<GeomType> Create()
{
    DataSet<GeomType> ds;
    ds.fileName = "something";
    ds.input = std::make_shared<LoaderType<GeomType>>(&ds);
    return std::move(ds);
}

然后将其保留为

auto ds = DataSet<Line>::Create<InputCSV>();

现在LoaderType是一种模板类型,它采用可以在函数内部指定的单个模板参数。