如果存在从"双精度"到"T"的转换,则禁用构造函数



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

#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;
}

您可能希望使用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}) {}

现场示例

std::enable_if_t<std::is_convertible_v<double, Ty>>* = nullptr>

是您正在寻找的

相关内容

  • 没有找到相关文章

最新更新