【问题标题】:While using templates: error: no matching constructor for initialization of使用模板时:错误:没有匹配的构造函数用于初始化
【发布时间】:2023-03-25 15:20:02
【问题描述】:

有一个命名空间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>       &vertices;
        const std::vector<IndexedFaceType>  &faces;
        const TreeType                      &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>       &vertices;
        const std::vector<IndexedFaceType>  &faces;
        const TreeType                      &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>        &vertices
                       , const std::vector<IndexedFaceType>     &faces
                       , const TreeType                         &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>        &vertices
                           , const std::vector<IndexedFaceType>     &faces
                           , const TreeType                         &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

【问题讨论】:

  • 另外我没有看到任何构造函数,你应该用 {} 初始化结构,请提供完整的“未注释”代码。

标签: c++ templates c++14


【解决方案1】:

您定义了一个没有任何用户定义的构造函数的聚合结构。你可以用aggregate initialisation初始化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 的一个特性:

聚合初始化的效果是:

每个直接公共基、(C++17 起)数组元素或非静态类成员,在 类定义中数组下标/外观的顺序是从复制初始化的 初始化列表的对应子句。

如果无法升级到 C++17 标准,则需要在派生结构中定义构造函数。

【讨论】:

    猜你喜欢
    • 2015-07-28
    • 1970-01-01
    • 2014-03-14
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多