【问题标题】:C++ - Template static method with templated parameter inside template class [duplicate]C ++ - 模板类中带有模板参数的模板静态方法[重复]
【发布时间】:2019-09-06 21:20:49
【问题描述】:

我有这两个类:

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 中的“重复”,因为不可能有其他任何东西。

【问题讨论】:

  • 不应该是template &lt;template&lt;typename&gt; LoaderType&gt;之类的吗?

标签: c++ templates


【解决方案1】:

您正在寻找的是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);
}

然后你继续使用 as

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

现在LoaderType 是一个模板类型,它接受一个您可以在函数内部指定的模板参数。

【讨论】:

  • 谢谢,它正在工作,但我必须使用template &lt;template&lt;typename&gt; typename LoaderType&gt;
  • @MartinPerry 是的。固定的。我不经常使用它们,所以有时我会弄错语法。
  • @NathanOliver 可以将问题标记为您在答案中的链接的欺骗吗?
  • 另外,使用...typename LoaderType&gt; 是一个新的 C++17 事物。在此之前,您必须使用...class LoaderType&gt;
  • @SergeyA 已修复。
猜你喜欢
  • 1970-01-01
  • 2011-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多