我重载了运算符<<
template <Typename T>
UIStream& operator<<(const T);
UIStream my_stream;
my_stream << 10 << " heads";
Run Code Online (Sandbox Code Playgroud)
工作但是:
my_stream << endl;
Run Code Online (Sandbox Code Playgroud)
给出编译错误:
错误C2678:二进制'<<':找不到哪个运算符带有'UIStream'类型的左操作数(或者没有可接受的转换)
做my_stream << endl工作的工作是什么?
使用以下代码可以清楚地解决该问题:
#include <functional>
#include <iostream>
#include <vector>
int main() {
//std::vector<int> a, b;
int a = 0, b = 0;
auto refa = std::ref(a);
auto refb = std::ref(b);
std::cout << (refa < refb) << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我使用注释std::vector<int> a, b;而不是int a = 0, b = 0;,则代码不会在GCC 5.1,clang 3.6或MSVC'13中的任何一个上编译.在我看来,std::reference_wrapper<std::vector<int>>可以隐式转换std::vector<int>&为LessThanComparable,因此它应该是LessThanComparable本身.有人可以向我解释一下吗?
c++ language-lawyer implicit-conversion c++11 reference-wrapper
可能重复:
通过隐式转换为字符串来流对象时,重载决策失败
我知道这样做并不是一个好主意,但我真的想知道下面的代码无法编译的原因(即为什么"没有可接受的转换"):
#include <iostream>
#include <string>
class Test
{
public:
operator std::string () const;
};
Test::operator std::string () const
{
return std::string("Test!");
}
int main ()
{
std::string str = "Blah!";
std::cout << str << std::endl;
Test test;
str = test;//implicitly calls operator std::string without complaining
std::cout << str << std::endl;
std::cout << test;//refuses to implicitly cast test to std::string
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在Visual Studio 2010上,我收到此错误:" error C2679: binary '<<' : no operator found which takes a right-hand operand …
请考虑以下代码.
#include <iostream>
#include <string>
struct SimpleStruct
{
operator std::string () { return value; }
std::string value;
};
int main ()
{
std::string s; // An empty string.
SimpleStruct x; // x.value constructed as an empty string.
bool less = s < x; // Error here.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码不能在g ++或Microsoft Visual C++上编译.编译器给出的错误报告是no match for operator '<' in 's < x'.问题是为什么编译器不是简单SimpleStruct x地string根据给定转换为operator string ()然后使用operator < ( string, string )?
编辑:继迈克·西摩的评论,我换成operator std::string () const;用operator char * () const;,并相应地改变了实现.这允许隐式转换,但是,由于某种原因,unsigned long int运算符优先于char*运算符,这只是感觉不对...而且,我不想暴露讨厌的C之类的东西,比如char*class,当我有std :: string时.我有一种预感,我的CustomizedInt类需要继承一些东西才能支持我想要的功能.有人可以详细说明迈克的评论std::basic_string吗?我不确定我是否理解得当.
我有这段代码:
#include <string>
#include <sstream>
#include <iostream>
class CustomizedInt
{
private:
int data;
public:
CustomizedInt() : data(123)
{
}
operator unsigned long int () const;
operator std::string () const;
};
CustomizedInt::operator unsigned long int () const
{
std::cout << "Called operator unsigned long int; ";
unsigned long int output;
output = (unsigned long int)data;
return output;
}
CustomizedInt::operator std::string () const
{ …Run Code Online (Sandbox Code Playgroud) 编辑:我重新格式化了帖子以便更清楚.
为什么这样做:
struct A {};
struct B {
B(A){}
};
void operator+(const B&, const B&) {}
int main()
{
A a1, a2;
a1 + a2;
}
Run Code Online (Sandbox Code Playgroud)
这不是吗?
struct B {
B(const char*){}
};
void operator+(const B&, const B&) {} //error: invalid operands of types 'const char [6]' and 'const char [6]' to binary 'operator+'|
int main()
{
"Hello" + "world";
}
Run Code Online (Sandbox Code Playgroud)
本质上,在第一个示例中a1,a2它们都B通过隐式转换转换为对象并使用operator+(const B&, const B&)添加.
从这个例子开始,我希望"Hello"并再次通过隐式构造函数"world"转换为B对象,并使用 …
struct A {};
struct B
{
B (A* pA) {}
B& operator = (A* pA) { return *this; }
};
template<typename T>
struct Wrap
{
T *x;
operator T* () { return x; }
};
int main ()
{
Wrap<A> a;
B oB = a; // error: conversion from ‘Wrap<A>’ to non-scalar type ‘B’ requested
oB = a; // ok
}
Run Code Online (Sandbox Code Playgroud)
什么时候oB被构造然后为什么B::B(A*)不被调用Wrap<T>::operator T ()?[注意:在下一个声明中B::operator = (A*)调用Wrap<T>::operator T ()]
我有一个结构作为其他类型的包装器,如下所示:
template<typename T>
struct A {
A& operator=(const T& value){
m_value = value;
return *this;
}
operator T() const {
return m_value;
}
private:
T m_value;
};
Run Code Online (Sandbox Code Playgroud)
我这样使用它:
int main() {
A<int> a;
a = 5; // Copy assignment constructor
std::cout << a << "\n"; // Implicit conversion to int
}
Run Code Online (Sandbox Code Playgroud)
它按预期工作.使用非基本类型时出现问题,如下例所示:
int main() {
A<std::complex<int>> c;
c = std::complex<int>(2, 2);
std::cout << c << "\n";
}
Run Code Online (Sandbox Code Playgroud)
上面的代码段会引发invalid operands to binary expression错误.
为什么会出现此错误?为什么不超载运营<<的std::complex<int>与隐式转换使用A<std::complex<int>> …
#include <iostream>
struct Int {
int i;
operator int() const noexcept {return i;}
};
int main() {
Int i;
i.i = 1;
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
但是,这无法在GCC 4.8.1上编译:
#include <iostream>
#include <string>
struct String {
std::string s;
operator std::string() const {return s;}
};
int main() {
String s;
s.s = "hi";
std::cout << s;
}
Run Code Online (Sandbox Code Playgroud)
以下是错误的相关部分:
错误:'operator <<'不匹配(操作数类型是'std :: ostream {aka std :: basic_ostream}'和'String')
std :: cout << s;SNIP
template std :: basic_ostream <_CharT,_Traits>&std :: …
我有一个带字符串转换运算符的Foobar类:
#include <string>
class Foobar
{
public:
Foobar();
Foobar(const Foobar&);
~Foobar();
operator std::string() const;
};
Run Code Online (Sandbox Code Playgroud)
我试图像这样使用它:
// C++源文件
#include <iostream>
#include <sstream>
#include "Foobar.hpp"
int main()
{
Foobar fb;
std::stringstream ss;
ss << "Foobar is: " << fb; // Error occurs here
std::cout << ss.str();
}
Run Code Online (Sandbox Code Playgroud)
我是否需要为Foobar明确创建一个运算符<<.我不明白为什么这是必要的,因为FooBar在放入iostream之前被转换为字符串,而std :: string已经有了operator << defined.
那么为什么这个错误呢?我错过了什么?
[编辑]
我刚刚发现,如果我改变了行,就会发生错误,对此:
ss << "Foobar is: " << fb.operator std::string();
Run Code Online (Sandbox Code Playgroud)
它编译成功.呃......!为什么编译器不能进行自动转换(Foobar - > string)?
什么是解决这个问题的"最佳实践"方法,所以我不必使用上面的丑陋语法?