- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试整理一些代码。
我有 16 个类,它们都有一些共同的功能,我用宏抽象了这些功能:
#define COMMON4( CLASS, BASE, ASSIGN, CHECK ) \
explicit CLASS( PyObject* pyob, bool owned=false ) \
: BASE{ pyob, owned } { \
validate(); } \
\
CLASS& operator=( const Object& rhs ) { \
return *this = rhs.ptr(); } \
\
CLASS& operator=( PyObject* rhsp ) { \
if(ptr()!=rhsp) set(ASSIGN); return *this; } \
\
bool accepts( PyObject* pyob ) const override { \
return pyob && CHECK; }
#define COMMON5( CLASS, BASE, CHECK ) \
COMMON4( CLASS, BASE, rhsp, CHECK ) \
CLASS( const Object& ob ) : BASE{ ob.ptr() } { \
validate(); } \
// Class Type
class Type: public Object
{
public:
COMMON5( Type, Object, _Type_Check(pyob) )
Type( const Type& t ) : Object{t} { validate(); }
};
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
class Boolean: public Object
{
public:
COMMON5( Boolean, Object, PyObject_IsTrue(pyob) != -1 )
Boolean( const Boolean& ob ) : Object{ob} { validate(); }
Boolean( bool v=false ) { set( PyBool_FromLong(v?1:0), true ); validate(); } // create from bool
Boolean& operator=( bool v ) { set( PyBool_FromLong(v?1:0), true ); return *this; }
operator bool() const { return as_bool(); }
};
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
class Long: public Object
{
public:
COMMON4( Long, Object, PyNumber_Long(rhsp), _Long_Check(pyob) )
// π I *think* the explicit was originally on the wrong function below
explicit Long( const Long& ob ) : Object{ ob } { validate(); }
Long( const Object& ob ) : Object{ PyNumber_Long(ob.ptr()) , true } { validate(); } // ... any object
:
}
: (etc)
不过,我刚刚发现C++11支持构造函数继承,例如:
#include <string>
#include <iostream>
using namespace std;
class B {
public:
B() { cout << "B:-\n"; }
B(int i) { cout << "B:int\n"; }
B(float i) { cout << "B:float\n"; }
};
class D : public B {
using B::B;
public:
D(double i) : B() { cout << "D:double\n"; }
};
class D2 : public B {
using B::B;
public:
D2(float i) : B() { cout << "D:float\n"; }
};
class D3 : public B {
using B::B;
public:
D3(float i) = delete;
};
int main() {
D a{5}; // B:int
D b{5.f}; // B:float
D c{5.}; // B:- D:double
D2 d{5.f}; // B:- D:float
//D3 e{5.f}; // error: use of deleted function 'D3::D3(float)'
}
此代码表明可以回退到基类构造函数,同时提供覆盖它们的机会。
这正是我所需要的,因为偶尔会有类(class)稍微打破模式。
这是重写:
using CheckType = bool(PyObject*);
inline PyObject* setDefault(PyObject* pyob){ return pyob; };
template< typename Derived, typename Base, CheckType checkfunc, decltype(setDefault) setfunc = setDefault >
class ObjBase : public Object
{
public:
ObjBase(){ };
explicit ObjBase( PyObject* pyob, bool owned=false ) : Base{pyob,owned} { validate(); }
Derived& operator=( const Object& rhs ) { return *this = rhs.ptr(); }
Derived& operator=( PyObject* rhsp ) { if(ptr()!=rhsp) set(setfunc(rhsp)); return *this; }
bool accepts( PyObject* pyob ) const override { return pyob && checkfunc(pyob); }
ObjBase( const Object& ob ) : Base{ob.ptr()} { validate(); }
};
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// Class Type
class Type: public ObjBase< Type, Object, _Type_Check > {
using ObjBase< Type, Object, _Type_Check >::ObjBase;
using ObjBase< Type, Object, _Type_Check >::operator=;
public:
// COMMON5( Type, Object, _Type_Check(pyob) )
Type( const Type& t ) : ObjBase{t} { validate(); }
};
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
inline bool bool_check( PyObject* pyob ){ return PyObject_IsTrue(pyob) != -1; }
class Boolean: public ObjBase< Boolean, Object, bool_check > // <-- 1. Candidate is the implicit copy assignment operator
{
using ObjBase< Boolean, Object, bool_check >::ObjBase;
using ObjBase< Boolean, Object, bool_check >::operator=;
public:
// COMMON5( Boolean, Object, PyObject_IsTrue(pyob) != -1 )
Boolean( const Boolean& ob ) : ObjBase{ob} { validate(); }
Boolean( bool v=false ) { set( PyBool_FromLong(v?1:0), true ); validate(); } // create from bool
Boolean& operator=( bool v ) { set( PyBool_FromLong(v?1:0), true ); return *this; } // <-- 2. Candidate function
operator bool() const { return as_bool(); }
};
:
: (etc)
第一类作品——类型。但是,当我尝试使用此类时, bool 类会导致编译器错误。
错误:重载运算符“=”的使用不明确(操作数类型为“Py::Boolean”和“Py::Long”)
Boolean b{true};
Long l{15};
b = l; // <-- ERROR: Use of overloaded operator '=' is ambiguous (with operand types 'Py::Boolean' and 'Py::Long')
错误指定了我在代码中标记的两个候选人:
// Candidate function
Boolean& operator=( bool v ) { set( PyBool_FromLong(v?1:0), true ); return *this; }
但另一个指向类声明本身的行:
// Candidate is the implicit copy assignment operator
class Boolean: public ObjBase< Boolean, Object, bool_check > // <-- ?!
{ ...
就是这个我不明白。
我的第一个猜测是与基类中的赋值运算符存在一些冲突。
但是,错误具体是说“Candidate is the implicit copy assignment operator”
查找“隐式复制赋值运算符”,http://en.cppreference.com/w/cpp/language/as_operator
...表示生成了一个隐式复制赋值,但如果满足特定条件则将其删除。
我的猜测是原来的类(class)符合这些标准。但是将大多数方法移回基类的行为可能意味着现在没有满足这些标准。
但是,我看不到。
如何插入这一进程?
编辑:完整的源文件列表here
编辑:我还注意到,通过将 operator= 重载移回 ObjBase,'*this' 现在不正确了。将其替换为“static_cast(*this)”会产生额外的错误。
最佳答案
第二个候选者可能是隐式定义的复制赋值运算符,它未在源代码中显示,因此编译器指向类本身。
您的 Long
类可以隐式转换为各种可转换为 bool
的整数类型,这些类型也可以转换为 Boolean
,并且这两种类型都可以分配给 Boolean
,因此编译器在执行分配之前不知道要转换成哪个。
您可以显式转换,这样编译器就不需要检查:
b = bool(l);
或等效地,但更明确(对于某些读者来说可能更清楚):
b = static_cast<bool>(l);
您可能希望避免在类型之间进行过多的显式转换,这会造成混淆并导致此类问题。要禁用隐式转换并要求显式转换以告诉编译器您要执行哪些转换,请将转换构造函数设置为 explicit
,或将转换运算符设置为 explicit
(或两者)。
关于c++ - "Ambiguous resolution"选择性构造函数继承错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27093008/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!