我有一个Rectangle类转换运算符,double并且std::string:
class Rectangle
{
public:
Rectangle(double x, double y) : _x(x), _y(y) {}
operator std::string ();
operator double ();
private:
double _x, _y;
double getArea() {return _x * _y;}
};
int main()
{
Rectangle r(3, 2.5);
cout << r << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么operator double()被调用,而不是operator std::string().据我所知,根据C++ wikibook,
operator double用于将Rectangle对象转换为double.
那么这里发生了什么?是否与int传递给构造函数的事实有关?如果是这样,为什么?
它只是偏好还是有特定的情况,其中一个是必要的而不是另一个?我正在参考以下变体进行初始化
T t(e); // direct initialization
T t = e; // copy initialization
Run Code Online (Sandbox Code Playgroud) c++ explicit-constructor implicit-conversion copy-initialization
我写
object MyString {
implicit def stringToMyString(s: String) = new MyString(s)
}
class MyString(str: String) {
def camelize = str.split("_").map(_.capitalize).mkString
override def toString = str
}
object Parse {
def main(args: Array[String]) {
val x = "active_record".camelize
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
在我的程序中.这会导致编译错误.我插入后
import MyString.stringToMyString
Run Code Online (Sandbox Code Playgroud)
然后它工作.
从Odersky的Scala编程中我得到了源的伴随对象中的隐式转换,或者不需要导入预期的目标类型.
我正在考虑通过将它们包装在自定义中来使原始.NET值类型更加类型安全并且更"自我记录" struct.但是,我想知道它是否真的值得在现实世界的软件中付出努力.
(这种"努力"可以在下面看到:必须一次又一次地应用相同的代码模式.我们声明
structs,因此不能使用继承来删除代码重复;并且由于必须声明重载的运算符static,因此必须定义它们对于每种类型单独.)
拿这个(公平地说是微不足道的)例子:
struct Area
{
public static implicit operator Area(double x) { return new Area(x); }
public static implicit operator double(Area area) { return area.x; }
private Area(double x) { this.x = x; }
private readonly double x;
}
struct Length
{
public static implicit operator Length(double x) { return new Length(x); }
public static implicit operator double(Length length) { return length.x; }
private Length(double x) { this.x = x; }
private readonly …Run Code Online (Sandbox Code Playgroud) 以下是否会出现编译错误?
delete cout;
delete cin;
Run Code Online (Sandbox Code Playgroud)
答案是不.
它是标准库中流类实现的一个缺陷.它们具有以下要转换的转换函数void*,这意味着,所有流对象都可以隐式转换为void*:
operator void * ( ) const;
Run Code Online (Sandbox Code Playgroud)
这一般非常有用,因为它可以让我们在从文件读取输入时编写非常惯用的循环.但与此同时,它让用户可以写delete stream.正如我所说,您可以删除任何流对象.所以这些都是允许的:
delete ss; //declare std::stringstream ss;
delete iss; //declare std::istringstream iss;
delete oss; //declare std::ostringstream oss;
Run Code Online (Sandbox Code Playgroud)
只有他们会发出警告,说(见ideone):
警告:删除'void*'未定义
你可以轻易地通过铸造来避免,比如说char*.但该程序仍然存在问题,并且在运行时很可能会崩溃.
-
所以我的问题是,在C++ 11中这个问题已得到解决和修复吗?以下文章提供了此问题的一个修复:
-
编辑:
来自@ Xeo对@ Alf答案的评论:
提出修复此问题的论文:
我很困惑,为什么以下代码无法编译
int foo(const float* &a) {
return 0;
}
int main() {
float* a;
foo(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器给出错误:
错误:从'float*'类型的表达式初始化'const float*&'类型的引用无效
但是当我尝试在foo中没有引用时传递,它编译正常.
我认为它应该表现出相同的行为,无论我是否通过引用.
谢谢,
我正在尝试将数字转换成字母.我正在制作一组需要数字或数字和字母的div.所以1-3只是1-3.但4-13需要是/ 4,b/5,c6等.有没有办法可以轻松地将这些数字转换成字母.也许将ascii值改变一定量?
for(var i = 1; i < 33; i++){
if( i < 4 || (i > 13 && i < 20) || i > 29){
$('#teeth-diagram').append("<div class='tooth' id='" + i + "'> </div>");
}else{
$('#teeth-diagram').append("<div class='tooth' id='" + Letter goes here + "/" + i + "'> </div>");
}
}
Run Code Online (Sandbox Code Playgroud) 这是Explicit ref-qualified转换运算符模板的后续操作.我已经尝试了许多不同的选项,我在这里给出了一些结果,试图看看最终是否有任何解决方案.
假设一个类(例如任何一个)需要以方便,安全(无意外)的方式提供转换到任何可能的类型,以保留移动语义.我可以想到四种不同的方式.
struct A
{
// explicit conversion operators (nice, safe?)
template<typename T> explicit operator T&& () &&;
template<typename T> explicit operator T& () &;
template<typename T> explicit operator const T& () const&;
// explicit member function (ugly, safe)
template<typename T> T&& cast() &&;
template<typename T> T& cast() &;
template<typename T> const T& cast() const&;
};
// explicit non-member function (ugly, safe)
template<typename T> T&& cast(A&&);
template<typename T> T& cast(A&);
template<typename T> const …Run Code Online (Sandbox Code Playgroud) c++ implicit-conversion move-semantics explicit-conversion c++11
这个问题的灵感来自于std :: reference_wrapper的问题.让我们说,例如,operator<对于std::vector.它被定义为函数模板
template< class T, class Alloc >
bool operator<( const vector<T,Alloc>& lhs,
const vector<T,Alloc>& rhs );
Run Code Online (Sandbox Code Playgroud)
因此,拒绝将函数参数隐式转换为相应函数参数的类型(主要是因为其模板性质).这大大降低了它的实用性和便利性std::reference_wrapper.例如,您不能使用std::sort的std::vector<std::reference_wrapper<std::vector<int>>>.
另一方面,只有当operator<定义为非模板Koenig运算符时,才能解决所有问题
template <...>
class vector ... {
friend bool operator<(const vector& a, const vector& b) {...}
};
Run Code Online (Sandbox Code Playgroud)
我想知道为什么标准库采用了前一种方法而不是这种方法?
c++ standard-library implicit-conversion c++11 reference-wrapper
我很难理解为什么以下代码不允许隐式转换发生.
#include <string>
using namespace std;
struct HasConversionToString {
HasConversionToString(const string& s_) : s{s_} {}
string s;
operator const string&() const { return s; }
};
int main() {
string s{"a"};
HasConversionToString obj{"b"};
return s < obj;
}
Run Code Online (Sandbox Code Playgroud)
clang和gcc都找不到一种有效的方法来比较两个对象的错误:
clang++ -std=c++14 -Wall -Wextra -pedantic conversion.cpp -o test
conversion.cpp:13:12: error: invalid operands to binary expression ('string' (aka 'basic_string<char>') and 'HasConversionToString')
return s < obj;
~ ^ ~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.0/../../../../include/c++/5.3.0/bits/stl_pair.h:220:5: note: candidate template ignored: could not match
'pair' against 'basic_string'
operator<(const pair<_T1, _T2>& …Run Code Online (Sandbox Code Playgroud)