c++ - 使用模板时:错误:没有匹配的构造函数用于初始化

标签 c++ templates c++14

有一个带有detail::RayIntersectorHits的 namespace :

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

最佳答案

您已经定义了没有任何用户定义的构造函数的聚合结构。您可以使用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的功能:

The effects of aggregate initialization are:

Each direct public base, (since C++17) array element, or non-static class member, in order of array subscript/appearance in the class definition is copy-initialized from the corresponding clause of the initializer list.



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

关于c++ - 使用模板时:错误:没有匹配的构造函数用于初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64293637/

相关文章:

c++ - 使用 Win32 API 列出存储在纯资源库 (DLL) 中的消息 ID 和符号名称

c++ - 是 (int)(unsigned)-1 == -1 未定义的行为

c++ - 模板参数推导和 SFINAE - 使用 std::enable_if

c++ - 如何在现代 C++ 中实现经典的排序算法?

c++ - 元编程技巧 : how to simplify implementation of two metafunctions

c++ - 如果比较函数不是运算符 <,为什么 std::sort 会崩溃?

c++ - 编译时模板实例化检查

c++ - 模板,没有调用错误的匹配函数

c++ - 将 std::tuple 转换为 std::set

c++ - Damerau–Levenshtein distance (Edit Distance with Transposition) c实现