C++ 如果存在从'double'到'T'的转换,SFINAE将禁用构造函数`
下面是我能想出的最基本的有意义的程序来重现我在这个问题上的困境。由于C++ 如果存在从'double'到'T'的转换,SFINAE将禁用构造函数`,c++,templates,operator-overloading,c++14,sfinae,C++,Templates,Operator Overloading,C++14,Sfinae,下面是我能想出的最基本的有意义的程序来重现我在这个问题上的困境。由于LinearForm的构造函数之间存在冲突,程序无法编译。要解决此冲突,我想启用LinearForm::LinearForm(double)当且仅当不存在从double到V的转换时。我该怎么做?(它会解决施工人员之间的冲突吗?) #包括 #包括 模板 结构向量{ std::阵列坐标; 向量(std::数组坐标):坐标(坐标){} //标量和向量之间的隐式转换 模板 向量(双标量):坐标(标量){} 模板 运算符double()常
LinearForm
的构造函数之间存在冲突,程序无法编译。要解决此冲突,我想启用LinearForm::LinearForm(double)
当且仅当不存在从double
到V
的转换时。我该怎么做?(它会解决施工人员之间的冲突吗?)
#包括
#包括
模板
结构向量{
std::阵列坐标;
向量(std::数组坐标):坐标(坐标){}
//标量和向量之间的隐式转换
模板
向量(双标量):坐标(标量){}
模板
运算符double()常量{return coords[0];}
双点(矢量u)常数{
双acc=0;
对于(int i=0;i您可能需要使用。然后,这将完成以下工作:
模板
LinearForm(双v):LinearForm(v::zero())
{
如果(v!=0){
抛出std::runtime_错误(“LinearForm不能是非零常量”);
}
}
要编译您的代码,我还需要添加两件事:
LinearForm(int值):v(值){
修改
模板
向量(双标量):坐标(标量){}
到
模板
向量(双标量):坐标({scalar}){}
您可能需要使用。然后,这将完成以下工作:
模板
LinearForm(双v):LinearForm(v::zero())
{
如果(v!=0){
抛出std::runtime_错误(“LinearForm不能是非零常量”);
}
}
要编译您的代码,我还需要添加两件事:
LinearForm(int值):v(值){
修改
模板
向量(双标量):坐标(标量){}
到
模板
向量(双标量):坐标({scalar}){}
std::如果\u t*=nullptr>
是您正在搜索的内容std::enable\u if\u t*=nullptr>
这就是你要找的
#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::enable_if_t<std::is_convertible_v<double, Ty>>* = nullptr>