This question already has an answer here:
call of overloaded with ref-qualifiers member function is ambiguous
(1 answer)
Closed 7 years ago.
The following code uses return type deduction (auto) and different methods for L-value and R-value objects. It seems when combining the two, gcc 4.9.2 has problems with overload resolution: "call of overloaded 'f()' is ambiguous".
Is this a bug or just another strange C++ corner case? Clang accepts it as expected.
struct T {
auto f() & {
return int{0};
}
auto f() && {
return string{""};
}
};
void test_it() {
//Calling with L-value object. Fails with "call of overloaded 'f()' is ambiguous").
T t;
int s = t.f();
//Calling with R-value object. Fails with "call of overloaded 'f()' is ambiguous").
string i = T{}.f();
}
The example can be studied using online compilers here:
gcc 4.9.2: http://goo.gl/IE19y8
clang 3.5.1: http://goo.gl/FRbD8Z
It turned out to be a known bug:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60943
Related
This question already has answers here:
Static member access in constant expressions
(2 answers)
Closed 3 years ago.
I've discovered that calling a constexpr static method using a constant reference argument leads to an error "expression is not an integral constant" for both clang and icc, but not for gcc or msvc (https://godbolt.org/z/PewOVc):
struct S
{
static constexpr bool ok() { return true; }
};
constexpr void ff(const S &s) // OK for everyone if not a ref
{
static_assert(s.ok(), "oops!"); // ERROR clang/icc, OK gcc/msvc
static_assert(S::ok(), "oops!"); // OK for everyone
}
If argument is not a reference then code compiles by any of these compilers. Who is right/correct here?
The C++ standard disqualifies evaluated id-expressions that have reference types from participating in constant-expressions (unless some more constraints are met, which is not the case for this code).
However gcc seems to ignore this rule. The same result (gcc accepts, clang rejects) can be obtained with this simplified function:
constexpr void ff(const int &s)
{
static_assert((s, true), "oops!");
}
So the problem has nothing to do with static member functions. My interpretation is that this is a gcc bug.
I did not check msvc, maybe the bug is different there but it's still wrong.
This question already has an answer here:
Why can't one compare a function pointer to a template function without explicit & on function name?
(1 answer)
Closed 3 years ago.
i hit an error on gcc that doesn't occur on clang
template<typename T>
int invoke_func(T a) {
return a;
}
bool test(int(*ptr)(int))
{
return ptr == invoke_func<int>;
}
godbolt
error:
<source>: In function 'bool test(int (*)(int))':
<source>:9:19: error: assuming cast to type 'int (*)(int)' from overloaded function [-fpermissive]
return ptr == invoke_func<int>;
^~~~~~~~~~~~~~~~
is gcc right to reject this code ?
after further testing replacing invoke_func<int> by &invoke_func<int> works on gcc and clang.
but why is the & required here when it isn't in expression like int(*ptr)(int) = invoke_func<int>; ?
godbolt
There is no overload resolution involved, so message is certainly a GCC bug at the very least. There appears to be a bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81059
Edit: When searching for standard rule, I stumbled upon an existing answer to a duplicate, which explains the corner case: Why can't one compare a function pointer to a template function without explicit & on function name?
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Is it possible to call a function which takes an rvalue reference to a function? For example:
#include <iostream>
void foo(void(&f)(int))
{
std::cout << "A" << std::endl;
}
void foo(void(&&f)(int))
{
std::cout << "B" << std::endl;
}
Can I call the overload of foo that prints "B"?
This is not possible.
When you have two candidate functions like these, the overload taking an lvalue reference to function type is always preferred over the rvalue reference overload. Functions are considered lvalues in all cases so the conversion to an lvalue reference is the strongest. Here is some standard wording ([over.ics.rank]/p3.2.4):
Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if
S1 and S2 are reference bindings (8.5.3) and S1 binds an lvalue reference to a function lvalue and S2 binds an rvalue reference to a function lvalue. [ Example:
int f(void(&)()); // #1
int f(void(&&)()); // #2
void g();
int i1 = f(g); // calls #1
— end example]
The code from my comment presented here calls overload #2 in gcc and is rejected by clang.
void foo(void(&)(int)); // #1
void foo(void(&&)(int)); // #2
void f(int);
struct wrap {
using T = void(&&)(int);
operator T() { return f; }
};
int main() {
foo(wrap{}); // Calls #2 in gcc, error in clang
}
The Clang error is:
non-const lvalue reference to type void (int) cannot bind to a temporary of type wrap
GCC is obviously wrong because of the above quote, but Clang is also wrong as well. The result of the operator function is an lvalue so it should bind to the lvalue overload, but it seems that clang is not attempting the conversion. A simpler example is:
void (&r)(int) = wrap{}; // OK in gcc, error in clang
So this looks like a bug in Clang and GCC.
This question already has answers here:
A lambda's return type can be deduced by the return value, so why can't a function's?
(5 answers)
Omit return type in C++11
(6 answers)
Closed 8 years ago.
My question is, why can't the return type of a function be deduced ? , or more simply why the following code gives error :
auto myfunc(int a)
{
int a = 12;
return a;
}
Why this isn't valid ?
It is a feature in C++14 , You can try it with GCC 4.9 or clang by setting the -std=c++1y flag.
Live Example : http://coliru.stacked-crooked.com/a/00b8b708d6f0f45b
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3638.html
It is allowed in C++14 (and is called automatic return type deduction), you may enable it in your compiler with std=c++1y for now.
You can use the trailing return type if your compiler supports c++11 but not c++14 :
auto myfunc(int a) -> int
{
int b = a;
return a;
}
This question already has answers here:
rvalue to lvalue conversion Visual Studio
(3 answers)
Closed 8 years ago.
I came to know that Temporaries connot be bound to non-const references.
class X
{
int i;
};
X fun()
{
return X();
}
void func(X &x)
{
}
int main()
{
func(fun());
return 0;
}
Isn't call to fun producing a temporary? Why can temporary be linked to non-const reference here. I am unable to comprehend as to why is this compiling fine.
EDIT:
I am using VS2010. I don't understand how should this matter.
Isn't call to fun producing a temporary?
Yes.
Why can temporary be linked to non-const reference here.
It can't.
I am unable to comprehend as to why is this compiling fine.
Because your compiler is faulty.
I am using VS2010. I don't understand how should this matter.
That compiler has many non-standard "extensions" to the language. This is just one example of dodgy code that's accepted by that compiler, but not a conformant one.