例如:
operator bool() const
{
return col != 0;
}
Run Code Online (Sandbox Code Playgroud)
col是一个int.operator bool() const工作怎么样?
在这里阅读关于转换运算符和构造函数的一些问题让我思考它们之间的相互作用,即当存在"模糊"调用时.请考虑以下代码:
class A;
class B {
public:
B(){}
B(const A&) //conversion constructor
{
cout << "called B's conversion constructor" << endl;
}
};
class A {
public:
operator B() //conversion operator
{
cout << "called A's conversion operator" << endl;
return B();
}
};
int main()
{
B b = A(); //what should be called here? apparently, A::operator B()
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码显示"被称为A的转换运算符",这意味着调用转换运算符而不是构造函数.如果operator B()从中删除/注释掉代码A,编译器将很乐意切换到使用构造函数(不对代码进行其他更改).
我的问题是:
B b = A();是一个模糊的调用,因此这里必须有某种类型的优先级.这个优先权究竟在哪里确定?(将赞赏C++标准的参考/引用)A对象应该如何成为一个B对象, …c++ constructor operators type-conversion conversion-operator
考虑这个简单的例子:
template <class Type>
class smartref {
public:
smartref() : data(new Type) { }
operator Type&(){ return *data; }
private:
Type* data;
};
class person {
public:
void think() { std::cout << "I am thinking"; }
};
int main() {
smartref<person> p;
p.think(); // why does not the compiler try substituting Type&?
}
Run Code Online (Sandbox Code Playgroud)
转换运算符如何在C++中工作?(即)编译器何时尝试替换转换运算符后定义的类型?
以下是什么是"operator int"函数?它有什么作用?
class INT
{
int a;
public:
INT(int ix = 0)
{
a = ix;
}
/* Starting here: */
operator int()
{
return a;
}
/* End */
INT operator ++(int)
{
return a++;
}
};
Run Code Online (Sandbox Code Playgroud) 下面的代码在Visual Studio 2013,gcc 4.8,clang 3.4和clang 3.5(Apple LLVM 6.0)中编译,但不在clang 3.6中编译(通过Apple LLVM 6.1)
代码是我们代码库中复杂类的简化版本,这是展示问题所需的最低要求.
问题的关键在于,复制结构TYPED_VALUE是在3.6中,STRING因为存在接受a的构造函数而对类型的模板化转换运算符进行求值STRING; 这导致std::is_constructible被评估导致它需要定义STRING(我们在这里不能提供 - 将导致完整代码中的循环依赖).
class STRING;
class TYPED_VALUE
{
public:
TYPED_VALUE( const TYPED_VALUE& ) = default; // explicit or implicit doesn't make a difference
TYPED_VALUE( const STRING & ) {}
template< typename TYPE, typename std::enable_if<!std::is_pointer< TYPE >::value && !std::is_constructible< TYPE, const STRING& >::value && !std::is_constructible< TYPE, bool >::value, int >::type = 0 >
operator TYPE( void ) const …Run Code Online (Sandbox Code Playgroud) clang conversion-operator language-lawyer overload-resolution c++11
请帮助我理解C++中转换运算符的确切运作方式.我在这里有一个简单的例子,我试图理解,虽然目前还不是很清楚编译器实际上是如何进行转换的.
class Example{
public:
Example();
Example(int val);
operator unsigned int();
~Example(){}
private:
int itsVal;
};
Example::Example():itsVal(0){}
Example::Example(int val):itsVal(val){}
Example::operator unsigned int (){
return (itsVal);
}
int main(){
int theInt = 5;
Example exObject = theInt; // here
Example ctr(5);
int theInt1 = ctr; // here
return 0;
}
Run Code Online (Sandbox Code Playgroud) C++ 中的类可以定义一个或多个转换运算符。其中一些可以自动推导结果类型:operator auto。所有编译器都允许程序员将任何运算符标记为已删除operator auto。对于具体类型,删除意味着尝试调用此类转换将导致编译错误。但这样做的目的可能是什么operator auto() = delete?
考虑一个例子:
struct A {
operator auto() = delete;
};
struct B : A {
operator auto() { return 1; }
};
int main() {
B b;
A a = b; // error in Clang
int i = b; // error in Clang and GCC
int j = a; // error in Clang and GCC and MSVC
}
Run Code Online (Sandbox Code Playgroud)
由于编译器无法推断出结果类型,因此它实际上禁止从此类或派生类进行任何转换,并出现错误:
function 'operator auto' with deduced return type cannot be …Run Code Online (Sandbox Code Playgroud) 我一直在反对一个简单易懂的想法,但我无法弄清楚如何用C++实现.
通常,我可以使用转换运算符声明一个类,如下例所示:
class Foo
{
private:
int _i;
public:
Foo( int i ) : _i(i) { }
operator int( ) const
{
return i;
}
};
Run Code Online (Sandbox Code Playgroud)
所以现在我可以写出很棒的东西了
int i = Foo(3);
Run Code Online (Sandbox Code Playgroud)
但在我的特定情况下,我想提供一个操作符,用于将对象转换为函数指针(例如,将Bar实例转换为int(*)(int, int)函数指针).这是我最初尝试的内容:
class Bar
{
private:
int (*_funcPtr)(int, int);
public:
Bar( int (*funcPtr)(int, int) ) : _funcPtr(funcPtr) { }
operator int(*)(int, int) ( ) const
{
return _funcPtr;
}
};
Run Code Online (Sandbox Code Playgroud)
但是运算符函数无法编译,生成这些错误:
expected identifier before '*' token
'<invalid-operator>' declared as a function returning a function
Run Code Online (Sandbox Code Playgroud)
我也尝试过上面的简单变体,比如在括号中包含返回类型,但所有这些想法也都失败了. …
clang和gcc在以下代码的行为上有所不同:
struct foo
{
foo(int);
};
struct waldo
{
template <typename T>
operator T();
};
int main()
{
waldo w;
foo f{w};
}
Run Code Online (Sandbox Code Playgroud)
clang接受此代码,并foo(int)调用构造函数.但是,gcc抱怨foo(int)构造函数和隐式生成的复制和移动构造函数之间存在歧义:
test.cpp: In function 'int main()':
test.cpp:15:12: error: call of overloaded 'foo(<brace-enclosed initializer list>)' is ambiguous
foo f{w};
^
test.cpp:15:12: note: candidates are:
test.cpp:3:5: note: foo::foo(int)
foo(int);
^
test.cpp:1:8: note: constexpr foo::foo(const foo&)
struct foo
^
test.cpp:1:8: note: constexpr foo::foo(foo&&)
Run Code Online (Sandbox Code Playgroud)
谁是对的?
值得注意的foo f{w}是,如果更改为foo f(w)(注意从大括号到括号的更改),gcc和clang都会出错.这让我希望gcc对上面例子的行为(即给出错误)是正确的,否则初始化()和{}形式之间会出现奇怪的不一致.
编辑 …
我正在玩下面的代码。
#include <iostream>
struct To
{
To() = default;
To(const struct From&) {std::cout << "Constructor called\n";}
To(const To&) {std::cout << "Copy constructor called\n";}
};
struct From
{
operator To(){std::cout << "Conversion called\n"; return To();}
};
int main()
{
From f;
To t(f);
To t1 = f;
To t2{To(f)};
}
Run Code Online (Sandbox Code Playgroud)
如果我-std=c++14同时使用GCC和Clang同意以下输出。
Constructor called
Conversion called
Constructor called
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用 进行编译-std=c++17,则两个编译器都同意
Conversion called
Conversion called
Conversion called
Run Code Online (Sandbox Code Playgroud)
我知道将几个预期的输出行减少为输出 3 行是由于复制省略,但我无法弄清楚 C++17 中发生了什么变化导致了此输出。究竟是什么标准的变化引发了这种情况?
c++ ×9
c++11 ×2
operators ×2
c++14 ×1
c++17 ×1
clang ×1
constructor ×1
templates ×1
terminology ×1