gpt4 book ai didi

c++ - 是否可以从一个特定模板实例化的构造函数中删除关键字 "explicit"?

转载 作者:太空宇宙 更新时间:2023-11-04 11:31:00 27 4
gpt4 key购买 nike

我正在尝试创建一个模板类来强制执行尺寸正确性(长度除以时间得出速度,等等)。

短篇小说:“无量纲”是可能的实例之一。如果我可以允许所有实例化显式地从 double 构造,并且进一步允许“无量纲”实例化(并且仅无量纲实例化)从 double 隐式构造,那将会很方便。

长话短说:我的模板类布局为

template<int iLength, int iTime, int iMass>
class qty {
double data;

//Operators overloaded to enforce dimensional correctness
// e.g. qty<a,b,c> can only be added to qty<a,b,c>
// qty<a,b,c> * qty<a2,b2,c2> returns qty<a+a2,b+b2,c+c2>

};

按照这种风格,qty<0,0,0>是一个无量纲量,所以应该可以添加或减去 qty<0,0,0>和一个双。我目前通过声明

强制执行此操作
    qty operator+ (const double& rhs) const;

...但仅为 qty<0,0,0> 定义 .这是可行的......但我认为我可以做得更好。如果我允许从 double 隐式转换为 qty<0,0,0> ,然后添加 double 和 qty<0,0,0>不需要特殊处理。用户错误也会给出更具暗示性的错误消息——尝试将速度加倍表示无法进行转换(了解维度不兼容的基本概念),而不是提示函数未定义(这可能会导致用户怀疑模板类中有错误)。

问题是我不允许对任何其他模板参数组合进行隐式构造。如果我这样做了,那么添加任何数量和加倍总是会成功;我想强制用户考虑维度的正确性,并在添加之前明确地将 double 常量转换为适当的维度(如果这是预期的操作)。但是,我确实希望允许 显式 从 double 构造 --- 没有它,简单的声明

qty<1,-1,0> a(1.5); //speed with value 1.5

需要一个笨拙的转换函数

qty<1,-1,0> a = makeQty<1,-1,0>( 1.5 ); //my eyes hurt

这意味着我真正想要的是

template<int iLength, int iTime, int iMass>
class qty {
double data;
explicit qty(const double& rhs) : data(rhs) {} //general version prohibits
//implicit conversion

//...
};

template<>
qty<0,0,0>::qty(const double&rhs) : data(rhs) {} //Explicit instantiation
//for dimensionless case
// ... with black magic to reallow implicit conversion
// for this instantiation only ???

如您所见,我不确定是否可以删除 explicit仅针对一个实例的规范,并且 --- 如果可能的话 --- 我不确定语法是什么。

最佳答案

我们创建一个 T 类型或您不能根据 bool 创建的类型:

template<bool b, typename T>
struct block_unless {
struct type { type() = delete; operator T(); }; // operator T is standard-paranoia
};
template<typename T>
struct block_unless<true, T> {
using type = T;
};
template<bool b, typename T>
using block_unless_t = typename block_unless<b,T>::type;
template<bool b, typename T>
using block_if_t = block_unless_t<!b, T>;

然后我们保护我们想要阻止/激活的方法与其余代码内联:

template<int a, int b, int c>
struct qty {
enum { scalar = (a==0)&&(b==0)&&(c==0) };
explict qty( block_if_t< scalar, double > d );
qty( block_unless_t< scalar, double > d );
};

怎么样?

在 C++1y 中,requires 子句可能会做得更好。

(标准的偏执狂是因为标准中的用语,其中模板方法必须至少有一个有效的实例化:虽然无法访问,operator T 意味着您的代码使用 d 将在代码需要 double 的 99% 的上下文中工作。)

关于c++ - 是否可以从一个特定模板实例化的构造函数中删除关键字 "explicit"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24746342/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com