Does std::cout have a return value?
Because the operands of cout << cout
are user-defined types, the expression is effectively a function call. The compiler must find the best operator<<
that matches the operands, which in this case are both of type std::ostream
.
There are many candidate operator overloads from which to choose, but I'll just describe the one that ends up getting selected, following the usual overload resolution process.
std::ostream
has a conversion operator that allows conversion to void*
. This is used to enable testing the state of the stream as a boolean condition (i.e., it allows if (cout)
to work).
The right-hand operand expression cout
is implicitly converted to void const*
using this conversion operator, then the operator<<
overload that takes an ostream&
and a void const*
is called to write this pointer value.
Note that the actual value resulting from the ostream
to void*
conversion is unspecified. The specification only mandates that if the stream is in a bad state, a null pointer is returned, otherwise a non-null pointer is returned.
The operator<<
overloads for stream insertion do have a return value: they return the stream that was provided as an operand. This is what allows chaining of insertion operations (and for input streams, extraction operations using >>
).
return value from possible type in std::variant through std::visit
The error messages suck, but the issue here is that all of the alternatives of the variant must have the same return type in the visitor. Your AllTypesOperatorOverload
does not obey this rule, returning a double
and an int
, which are not the same type.
The newest versions of libstdc++ or any version of libc++ produce much better error messages that explicitly tell you this (the following is word wrapped by me):
error: static_assert failed due to requirement '__visit_rettypes_match'
"std::visit requires the visitor to have the same return type for
all alternatives of a variant"
static_assert(__visit_rettypes_match,
This makes sense, because when you look at this line, what is the type of bar
?
auto bar = std::visit(AllTypesOperatorOverload(), foo);
If you were allowed to return differing types, bar
's type would depend on which alternative foo
holds at runtime. That can't work in C++.
Note that there are easier ways to create visitors for std::visit
that use lambdas instead of externally defined structs. You can use if constexpr
:
std::visit([](auto value) {
if constexpr (std::is_same_v<int, decltype(value)>) {
std::cout << "visiting int\n";
} else {
static_assert(std::is_same_v<double, decltype(value)>);
std::cout << "visiting double\n";
}
std::cout << "bar: " << value << '\n';
}, foo);
Or alternatively, you can define an overloaded
helper struct that lets you overload lambdas:
template <typename... Lambdas>
struct overloaded : Lambdas...
{
template <typename... Fns>
explicit constexpr overloaded(Fns&&... fns)
: Lambdas(std::forward<Fns>(fns))...
{}
using Lambdas::operator()...;
};
template <typename... Lambdas>
overloaded(Lambdas...) -> overloaded<Lambdas...>;
// Usage:
std::visit(overloaded{
[](int value) {
std::cout << "visiting int\n";
std::cout << "bar: " << value << '\n';
},
[](double value) {
std::cout << "visiting double\n";
std::cout << "bar: " << value << '\n';
}
}, foo);
Why can std::cout print the value of nullptr only if returned by a function?
Here is the meaning of nullptr from the CPP Standards [4.10]
- A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type. Such a conversion is called a null pointer conversion.
Something the CPP Standards specifies, is that it isn't a std::nullptr_t value, it evaluates to zero or a prvalue of type std::nullptr_t.
In your case, it's pretty much is an (TYPE) pointer to some extent, so when you try to paste it out, it pastes out it's type's value (Where it points to, but by itself it won't). Your function returns an int*, and you give it a nullptr. So what you are basically doing is giving an int* a value. nullptr by itself won't have a value but
int* abc = nullptr;
will.
Why do I get a number when I stream the result of tolower() to std::cout, but not when I use putchar()?
std::tolower()
and std::toupper()
functions return value is int. And std::cout
print the exact value that appears to it.
So cout<< tolower(s[i])<<endl
print ASCII value of the characters. But when you write putchar(toupper(s[i]))
then putchar()
function automatically converts the ASCII value to characters. That's why you get character as output.
In order to use cout<< tolower(s[i]) << endl
you need to typecast the ASCII value to character.
So write -
cout<< (char)(toupper[i]) <<endl;
cout<< (char)(tolower[i]) <<endl;
C++ return value without return statement
Strictly, this causes undefined behavior. In practice, since sqr
has return type int
, it will always return something, even if no return
statement is present. That something can be any int
value.
Add a return
statement and turn on warnings in your compiler (g++ -Wall
, for instance).
int sqr(int &x)
{
return x = x*x;
}
What's the difference between coutcout and cout&cout in c++?
cout << cout
is equivalent to cout << cout.operator void *()
. This is the idiom used before C++11 to determine if an iostream is in a failure state, and is implemented in std::ios_base
; it usually returns the address of static_cast<std::ios_base *>(&cout)
.
cout << &cout
prints out the address of cout
.
Since std::ios_base
is a virtual base class of cout
, it may not necessarily be contiguous with cout
. That is why it prints a different address.
Why doesn't std::queue::pop return value.?
So, whats the difference, pop function could have done the same thing.
It could indeed have done the same thing. The reason it didn't, is because a pop that returned the popped element is unsafe in the presence of exceptions (having to return by value and thus creating a copy).
Consider this scenario (with a naive/made up pop implementation, to ilustrate my point):
template<class T>
class queue {
T* elements;
std::size_t top_position;
// stuff here
T pop()
{
auto x = elements[top_position];
// TODO: call destructor for elements[top_position] here
--top_position; // alter queue state here
return x; // calls T(const T&) which may throw
}
If the copy constructor of T throws on return, you have already altered the state of the queue (top_position
in my naive implementation) and the element is removed from the queue (and not returned). For all intents and purposes (no matter how you catch the exception in client code) the element at the top of the queue is lost.
This implementation is also inefficient in the case when you do not need the popped value (i.e. it creates a copy of the element that nobody will use).
This can be implemented safely and efficiently, with two separate operations (void pop
and const T& front()
).
difference between printf() and std::cout with respect to pointers
The format specifier %p
prints a void *
, (untrue: so the char *
is implicitly converted to void *
) the char *
is converted to void *
before printing. (But this is actually undefined behavior, see comments. The correct way to do that would be printf("%p", (void *) str1);
) The corresponding C++ code would be std::cout << (void *) str1 << '\n';
.
The code std::cout << str1;
prints str1
as null terminated string. The corresponding C-code would be printf('%s', str1);
Related Topics
Enumdisplaydevices VS Wmi Win32_Desktopmonitor, How to Detect Active Monitors
Correct Format for Http Post Using Qnetworkrequest
Find Two Elements in an Array That Sum to K
Calculate System Time Using Rdtsc
Array of Pointers as Function Parameter
Recursion in C++ Factorial Program
How to Enforce the 'Override' Keyword
Braces Around String Literal in Char Array Declaration Valid? (E.G. Char S[] = {"Hello World"})
Std::Remove_If - Lambda, Not Removing Anything from the Collection
Do Function Pointers Need an Ampersand
How to Generate a Newline in a Cpp MACro
Ways to Detect Whether a C++ Virtual Function Has Been Redefined in a Derived Class
Narrowing Conversion from Unsigned to Double
How to Recursively Create a Folder in Win32
What Is the Purpose of a Declaration Like Int (X); or Int (X) = 10;