【问题标题】:Virtual method with unspecialized template argument具有非专用模板参数的虚拟方法
【发布时间】:2020-03-20 08:41:13
【问题描述】:
#include <iostream>
#include <array>
#include <vector>

using namespace std;

// Currently I have code much like this one:

template <const uint32_t N>
using VectorN = array<double, N>;


template <const uint32_t N>
class ITransformable {
public:
    virtual vector<VectorN<N>>&  positions() = 0;
};


class SomeTransformer {
public:
    template <const uint32_t N>
    void operator()(ITransformable<N>& transformable) const {
        /* implementation */
    }
};

// Then I want to create interface like this.

template <const uint32_t N>
class ITransformer {
public:
    virtual void operator()(ITransformable<N>& transformable) const = 0;
};

// And finally implement it for SomeTransformer:
// 
// Notice that class is not template, this is intentional.
//
// class SomeTransformer : public ITransformer<N> {
// public:
//     virtual void operator()(ITransformable<N>& transformable) const {
//         /* implementation */
//     }    
// }

实际上,现在对我来说似乎是不可能的。否则这个类将继承 无限数量的接口特化......

但是,至少对于有限的维数 N,是否有可能?

template &lt;template &lt;typename&gt; class C&gt; 似乎是相关的,但我不知道如何应用它。

编辑 我想要的是这样的:

class SomeTransformer : 
    public ITransformer<2>, 
    public ITransformer<3>, 
    public ITransformer<4>, 
    ..., 
    public ITransformer<N> { 
    /* ... */ 
};

对于代码中曾经使用过的任何 N。正如我所说,这似乎是不可能的。

【问题讨论】:

  • 您遇到的错误是什么?
  • 我还没有收到任何错误。我什至无法弄清楚它的语法。
  • template&lt;uint32_t N&gt; class SomeTransformer: public ITransformer&lt;N&gt; 是您想要的吗?即你的具体 SomeTransformer 需要是一个模板类,你只需将模板参数传递给它的基础类 ITransformer
  • 看起来有点奇怪,你想要一个有 N 个函数的类,它们都非常相似。真的有必要让 N 成为函数签名的一部分吗?也可以是函数参数吗?
  • 从所有实例派生将增加大小而不使用我认为的所有功能。总的来说,设计似乎被打破了......我不清楚潜在的用例!如果每个变压器都有 N 并且仅从 ITTransformer 派生,则可以,但不能从所有变压器派生...仅是我的建议,因为我不了解给定的问题!

标签: c++ templates c++14 template-specialization


【解决方案1】:

您可以实现您想要的或几乎实现的目标。这是我的建议:


#include <type_traits>
#include <utility>

template<std::size_t N>
struct ITransformer {};

template<class T>
class SomeTransformer_h { };

template<std::size_t... Indices>
class SomeTransformer_h<
    std::integer_sequence<std::size_t, Indices...>> :  
    public ITransformer<1 + Indices>... { };


template<std::size_t N>
class SomeTransformer : public SomeTransformer_h<
    std::make_index_sequence<N>
> { };

int main() {
    SomeTransformer<5> a;
    ITransformer<1>& ref = a;
    ITransformer<4>& ref2 = a;
    ITransformer<5>& ref3 = a;
}

现在对于任何N,它将使SomeTransformer 继承从1 到N 的所有ITransformer

【讨论】:

    【解决方案2】:

    由于N 没有在任何地方声明,你不能使用它。你需要这样的东西:

    class SomeTransformer : public ITransformer<5> {
    public:
        virtual void operator()(ITransformable<5>& transformable) const {
            /* implementation */
        }    
    };
    

    或将其设为模板类:

    template <uint32_t N>
    class SomeTransformer : public ITransformer<N> {
    public:
        virtual void operator()(ITransformable<N>& transformable) const {
            /* implementation */
        }    
    };
    

    更新

    C++ 中没有动态继承。因此,您想要达到的目标是不可能的。

    【讨论】:

    • 是的,我知道这些。我已经编辑了问题,希望现在更清楚我想要什么。
    • 最后,将转换器声明为模板是正确的解决方案。我最初想要的是废话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多