diff --git a/math/vecops/inc/ROOT/TVec.hxx b/math/vecops/inc/ROOT/TVec.hxx
index 3913c5f583d2bf8531ebc6a22383944ff7c43a11..834b613bd80c02f57e21f4139485feb71cdcbaad 100644
--- a/math/vecops/inc/ROOT/TVec.hxx
+++ b/math/vecops/inc/ROOT/TVec.hxx
@@ -253,6 +253,16 @@ public:
       fData = ilist;
       return *this;
    }
+
+   // conversion
+   template <typename U, typename = std::enable_if<std::is_convertible<T, U>::value>>
+   operator TVec<U>() const
+   {
+      TVec<U> ret(size());
+      std::copy(begin(), end(), ret.begin());
+      return ret;
+   }
+
    // accessors
    reference at(size_type pos) { return fData.at(pos); }
    const_reference at(size_type pos) const { return fData.at(pos); }
diff --git a/math/vecops/test/vecops_tvec.cxx b/math/vecops/test/vecops_tvec.cxx
index 617ea7a77acc18e10e3b78b0579e469fc2d74b2a..e5057566d76f54cf63b17e17638a4b50e5108c2d 100644
--- a/math/vecops/test/vecops_tvec.cxx
+++ b/math/vecops/test/vecops_tvec.cxx
@@ -78,6 +78,36 @@ TEST(VecOps, MoveCtor)
    EXPECT_EQ(v2.size(), 3u);
 }
 
+TEST(VecOps, Conversion)
+{
+   ROOT::Experimental::VecOps::TVec<float> fvec{1.0f, 2.0f, 3.0f};
+   ROOT::Experimental::VecOps::TVec<unsigned> uvec{1u, 2u, 3u};
+
+   ROOT::Experimental::VecOps::TVec<int>  ivec = uvec;
+   ROOT::Experimental::VecOps::TVec<long> lvec = ivec;
+
+   EXPECT_EQ(1, ivec[0]);
+   EXPECT_EQ(2, ivec[1]);
+   EXPECT_EQ(3, ivec[2]);
+   EXPECT_EQ(3u, ivec.size());
+   EXPECT_EQ(1l, lvec[0]);
+   EXPECT_EQ(2l, lvec[1]);
+   EXPECT_EQ(3l, lvec[2]);
+   EXPECT_EQ(3u, lvec.size());
+
+   auto dvec1 = ROOT::Experimental::VecOps::TVec<double>(fvec);
+   auto dvec2 = ROOT::Experimental::VecOps::TVec<double>(uvec);
+
+   EXPECT_EQ(1.0, dvec1[0]);
+   EXPECT_EQ(2.0, dvec1[1]);
+   EXPECT_EQ(3.0, dvec1[2]);
+   EXPECT_EQ(3u, dvec1.size());
+   EXPECT_EQ(1.0, dvec2[0]);
+   EXPECT_EQ(2.0, dvec2[1]);
+   EXPECT_EQ(3.0, dvec2[2]);
+   EXPECT_EQ(3u, dvec2.size());
+}
+
 TEST(VecOps, MathScalar)
 {
    ROOT::Experimental::VecOps::TVec<double> ref{1, 2, 3};