При использовании шаблонов: ошибка: нет подходящего конструктора для инициализации

#c #templates #c 14

#c #шаблоны #c 14

Вопрос:

Существует пространство имен с detail::RayIntersectorHits :

 namespace detail {

    template<typename AVertexType, typename AIndexedFaceType, typename ATreeType, typename AVectorType>
    struct RayIntersector {
        using VertexType        = AVertexType;
        using IndexedFaceType   = AIndexedFaceType;
        using TreeType          = ATreeType;
        using VectorType        = AVectorType;

        const std::vector<VertexType>       amp;vertices;
        const std::vector<IndexedFaceType>  amp;faces;
        const TreeType                      amp;tree;

        const VectorType                     origin;
        const VectorType                     dir;
        const VectorType                     invdir;
    };

    template<typename VertexType, typename IndexedFaceType, typename TreeType, typename VectorType>
    struct RayIntersectorHits : RayIntersector<VertexType, IndexedFaceType, TreeType, VectorType> {
        std::vector<igl::Hit>                hits;
    }

}
  

Я использую detail::RayIntersectorHits это так:

 template<typename VertexType, typename IndexedFaceType, typename TreeType, typename VectorType>
inline bool intersect_ray_all_hits(/* input agrs */)
{
    auto ray_intersector = detail::RayIntersectorHits<VertexType, IndexedFaceType, TreeType, VectorType> {
        vertices, faces, tree,
        origin, dir, VectorType(dir.cwiseInverse())
    };
    
    // ...
}
  

Но я получаю эту ошибку компиляции:

 error: no matching constructor for initialization of 'detail::RayIntersectorHits<Matrix<float, 3, 1, 2, 3, 1>, Matrix<int, 3, 1, 2, 3, 1>, Tree<3, float>, Matrix<double, 3, 1, 2, 3, 1> >'
    auto ray_intersector = detail::RayIntersectorHits<VertexType, IndexedFaceType, TreeType, VectorType> {
                           ^                                                                             ~
  

Я не могу понять, как обойти ошибку. Я ценю любую помощь.

Решаемая

Ошибка была устранена:

 namespace detail {
    template<typename AVertexType, typename AIndexedFaceType, typename ATreeType, typename AVectorType>
    struct RayIntersector {
        using VertexType        = AVertexType;
        using IndexedFaceType   = AIndexedFaceType;
        using TreeType          = ATreeType;
        using VectorType        = AVectorType;

        const std::vector<VertexType>       amp;vertices;
        const std::vector<IndexedFaceType>  amp;faces;
        const TreeType                      amp;tree;

        const VectorType                     origin;
        const VectorType                     dir;
        const VectorType                     invdir;
#ifdef CPP17_NOT_AVAILABLE
        // Aggregate initialization for the derived type is a C  17 feature
        // Trying to compile with C  14
        // If you can't upgrade to C  17 standard, you will need to define a constructor in the derived struct.
        RayIntersector(const std::vector<VertexType>        amp;vertices
                       , const std::vector<IndexedFaceType>     amp;faces
                       , const TreeType                         amp;tree
                       , const VectorType                    origin
                       , const VectorType                    dir
                       , const VectorType                    invdir)
            :
              vertices(vertices)
            , faces(faces)
            , tree(tree)
            , origin(origin)
            , dir(dir)
            , invdir(invdir)
        {}
#endif // CPP17_NOT_AVAILABLE
    };

    template<typename VertexType, typename IndexedFaceType, typename TreeType, typename VectorType>
    struct RayIntersectorHits : RayIntersector<VertexType, IndexedFaceType, TreeType, VectorType> {
        std::vector<igl::Hit>                hits;
#ifdef CPP17_NOT_AVAILABLE
        // Aggregate initialization for the derived type is a C  17 feature
        // Trying to compile with C  14
        // If you can't upgrade to C  17 standard, you will need to define a constructor in the derived struct.
        RayIntersectorHits(const std::vector<VertexType>        amp;vertices
                           , const std::vector<IndexedFaceType>     amp;faces
                           , const TreeType                         amp;tree
                           , const VectorType                    origin
                           , const VectorType                    dir
                           , const VectorType                    invdir)
            : RayIntersector<VertexType, IndexedFaceType, TreeType, VectorType>(vertices, faces, tree, origin, dir, invdir) {}
#endif // CPP17_NOT_AVAILABLE
    };
} // namespace detail
  

Комментарии:

1. Также я не вижу никакого конструктора, вы должны инициализировать структуру с помощью {}, пожалуйста, предоставьте полный ‘раскомментированный’ код.

Ответ №1:

Вы определили совокупную структуру, которая не имеет пользовательских конструкторов. Вы можете инициализировать struct RayIntersector с помощью агрегированной инициализации:

 struct A
{
    public:
    int a;
    int b;
};

struct B: public A
{
    int c;
};

void func()
{
    auto varA = A{1,2};   // Compiles with C  14
    auto varB = B{2,3,4}; // Compiles with C  17
}
  

Но агрегированная инициализация для производного типа является особенностью C 17:

Эффекты агрегированной инициализации:

Каждый элемент массива direct public base (начиная с C 17) или нестатический член класса в порядке подстрочного индекса / появления массива в определении класса инициализируется копированием из соответствующего предложения списка инициализаторов.

Если вы не можете перейти на стандарт C 17, вам нужно будет определить конструктор в производной структуре.