代码之家  ›  专栏  ›  技术社区  ›  Museful

SIMEAE禁用构造函数,如果转换从“双”到“T”存在

  •  0
  • Museful  · 技术社区  · 6 年前

    下面是我能想到的最有意义的程序来重现我在这个问题上的困境。由于的构造函数之间的冲突,程序无法编译 LinearForm<double> . 为了解决这场冲突,我想 LinearForm<V>::LinearForm(double) 当且仅当不存在转换时 double V . 我该怎么做?(它会解决构造器之间的冲突吗?)

    #include <type_traits>
    #include <array>
    
    template<int N>
    struct Vector{
        std::array<double,N> coords;
    
        Vector(std::array<double,N> coords) : coords(coords) {}
    
        // implicit conversions between scalar and Vector<1>
        template<int Nd = N, std::enable_if_t<Nd==1>>
        Vector(double scalar) : coords(scalar) {}
        template<int Nd = N, std::enable_if_t<Nd==1>>
        operator double() const {return coords[0];}
    
        double dot(Vector<N> u) const {
            double acc = 0;
            for(int i=0; i<N; i++){
                acc += coords[i]*u.coords[i];
            }
            return acc;
        }
    
        static Vector<N> zero(){ return Vector<N>(std::array<double,N>{}); }
    };
    
    template<typename V> // V is domain element type i.e. LinearForm maps from V to double
    struct LinearForm {
        V v;
        LinearForm(V v) : v(v) {}
    
        //template<typename Vd=V, typename = std::enable_if_t</* WHAT TO PUT IN HERE */>>
        LinearForm(double v) : LinearForm(V::zero())
        {
            if(v != 0){
                throw std::runtime_error("LinearForm cannot be non-zero constant.");
            }
        }
        double operator()(V u){return u.dot(v);}
    };
    
    int main()
    {
        LinearForm<Vector<2>> lf(Vector<2>({1,2}));
        LinearForm<Vector<2>> zf = 0;
    
        LinearForm<double> slf = 0;
    
        auto u = Vector<2>({3,4});
        lf(u); // returns some value
        zf(u); // should return zero for any u
    
        return 0;
    }
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   NutCracker    6 年前

    你可能想用 std::is_convertible

    template <typename Vd=V,
              typename std::enable_if_t<std::is_convertible<double, Vd>::value>::type* = nullptr>
    LinearForm(double v) : LinearForm(V::zero())
    {
        if(v != 0){
            throw std::runtime_error("LinearForm cannot be non-zero constant.");
        }
    }
    

    要编译代码,我还需要添加两项内容:

    LinearForm(int value) : v(value) {}
    

    并修改

    template<int Nd = N, std::enable_if_t<Nd==1>>
    Vector(double scalar) : coords(scalar) {}
    

    template<int Nd = N>
    Vector(double scalar) : coords({scalar}) {}
    

    Live example

        2
  •  1
  •   Alex.-    6 年前
    std::enable_if_t<std::is_convertible_v<double, Ty>>* = nullptr>
    

    是你要找的