I have written this simple C++ code to swap any two variables. It works for int and double, but doesn't work for complex numbers, any idea why?
#include <iostream>
#include <complex>
using std::cout;
using std::endl;
using std::complex;
template <class T>
inline void swap(T& d, T& s)
{
T temp = d;
d = s;
s = temp;
}
int main()
{
int m=5, n=10;
double x=5.3, y=10.6;
complex<double> r(2.4, 3.5), s(3.4, 6.7);
cout << "inputs: " << m << " , " << n << endl;
swap(m, n);
cout << "outputs: " << m << " , " << n << endl;
cout << "double inputs: " << x << " , " << y << endl;
swap(x, y);
cout << "double outputs: " << x << " , " << y << endl;
cout << "complex inputs: " << r << " , " << s << endl;
swap(r, s);
cout << "complex outputs: " << r << " , " << s << endl;
}
This is the error:
g++ 02.swap.template.cpp -o c.out.02
02.swap.template.cpp: In function ‘int main()’:
02.swap.template.cpp:37:13: error: call of overloaded ‘swap(std::complex<double>&, std::complex<double>&)’ is ambiguous
02.swap.template.cpp:37:13: note: candidates are:
02.swap.template.cpp:13:13: note: void swap(T&, T&) [with T = std::complex<double>]
/usr/include/c++/4.6/bits/move.h:122:5: note: void std::swap(_Tp&, _Tp&) [with _Tp = std::complex<double>]
name conflit, changing to ::swap solves the issue.
The problem is that argument-dependent lookup is applied because you are calling a function template. If you had a plain function, there would be no ambiguity:
#include <complex>
void swap(complex<double> & d, complex<double> & s)
{
complex<double> temp = d;
d = s;
s = temp;
}
int main()
{
std::complex<double> r(2.4, 3.5), s(3.4, 6.7);
swap(r, s);
}
This is because of C++11 3.4.2:
Let X be the lookup set produced by unqualified lookup (3.4.1) and let Y be the lookup set produced by argument dependent lookup (defined as follows). If X contains
— a declaration of a class member, or
— a block-scope function declaration that is not a using-declaration, or
— a declaration that is neither a function or a function template
then Y is empty. Otherwise Y is the set of declarations found in the namespaces associated with the argument types as described below. The set of declarations found by the lookup of the name is the union of X and Y.
In the above case, X contains a block-scope function declaration.
However, if the unqualified lookup finds the function template you provided, then the ADL rules say that the argument-dependent lookup set is also considered. Since std::complex<double> lives in the std namespace, this namespace is also searched for the name swap, which already exists (by 20.2.2).
You can prevent argument-dependent lookup by wrapping the function name in parentheses:
(swap)(r, s);
This way, only the unqualified lookup is considered.
The compiler says it is confused because of two functions : yours and the standard std::swap. It consider std::swap too because std::complex is member of std::namespace, it's calling Argument Dependant Lookup. If you want to explicitly test your swap, you can use :: scope resolution operator, ie ::swap instead of swap. It will make another kind of lookup : Qualified Name Lookup solving the ambiguity.
Nonetheless, std::swap works well and do the job, except as exercise, include utility standard header, make a using std::swap, and it will work fine :
#include<utility>
//before needed (closest)
using std::swap;
swap(/*arguments*/);
Related
I am testing the following code with c++ templates. I have written a square function using int and float and with a function template.
#include <iostream>
using namespace std;
int square (int a){
cout << "int function" << endl;
return a*a;
};
float square (float a){
cout << "float function" << endl;
return a*a;
};
template <typename T>
T square (T x){
cout << "template function" << endl;
return x*x;
}
int main(){
cout << square<int>(5) << endl;
cout << square<float>(5.5) << endl;
cout << square(5) << endl;
cout << square(5.5) << endl;
return 0;
}
The output is
template function
25
template function
30.25
int function
25
template function
30.25
though I expected
template function
25
template function
30.25
template function
25
template function
30.25
Can someone explain the difference ?
It doesn't override anything, it's a better match. That is because 5.5 is a constant of type double, and not of type float.
You don't have any overload for doubles so the template gets instantiated. That's because the template doesn't require a conversion sequence from a double to a float, as opposed to your overload.
If you use a float constant, like so:
cout << square(5.5f) << endl;
It will print
float function
Template does not "override" regular function. Quite the opposite, regular functions usually "win" the overload resolution process, if they match argument types specified in the call. So, it is actually the other way around: all other things being equal, regular function "overrides" template function.
In your case the first two calls go to templates because you explicitly requested templates by using <> in the call. You explicitly prohibited the compiler to use regular functions.
The third call goes to the regular function, since it is an exact match and therefore it "wins", as I stated above.
The fourth call goes to the template version since the existing regular function is not an exact match (float parameter vs. double argument), while the template can be used to generate an exact match.
class Test{
public:
int work(){
cout << "in work " << endl;
return 0;
}
void work(int x){
//cout << "x = " << x << endl;
cout << "in work..." << endl;
}
};
int main(){
Test test;
std::function<void()> f = std::bind(&Test::work, &test);
thread th(f);
th.join();
return 0;
}
As above code, I want to bind member function void work(void) of a class (let's name it Test) , but occurs compiler error saying that can not determine which overrided function to use.
I can not change class Test since it belongs to a lib, how to achieve my goal? Thanks in advance!
Why don't skip std::bind altogether and use a lambda?
auto fp = [&t]() { t.test()};
As a bonus, your executable size will be smaller and your compiler has much easier time to inline the code if appropriate.
By casting it to the correct type:
std::function<void()> f = std::bind( static_cast<int (Test::*)()>(&Test::work), &test);
When deducing the template arguments to bind, the compiler is not in a context that allows function overload resolution - to be simplistic about it, it hasn't got that far yet.
Having deduced that the first argument is indeed the name of a member function pointer, it finds that there are two functions of the same name but of different types.
At this stage, they're both equally valid candidates (from the point of template argument deduction), therefore it's ambiguous
A static cast disambiguates because we're pushing the compiler beyond the stage where it has to deduce a template type - we have taken on the responsibility to template type deduction ourselves - by specifying the type in the static_cast.
So now all it has to do is overload resolution.
#include <functional>
#include <thread>
#include <iostream>
using namespace std;
class Test{
public:
int work(){
cout << "in work " << endl;
return 0;
}
void work(int x){
//cout << "x = " << x << endl;
cout << "in work..." << endl;
}
};
int main(){
Test test;
// only overload resolution required here
auto fp = static_cast<int (Test::*)()>(&Test::work);
// type is now unambiguous and overload resolution is already done
std::function<void()> f = std::bind(fp, &test);
thread th(f);
th.join();
return 0;
}
try this(member function ptr):
int main(){
Test test;
typedef int(Test:: *WKPtr)(void);
WKPtr p = &Test::work;
std::function<int()> f = std::bind(p, &test);
f();
return 0;
}
I'm trying to use an std::initializer_list as an argument in a function that uses argument-dependent lookup (ADL). But I don't get it to work and I don't understand why. The following is a minimal failing example:
#include <initializer_list>
#include <iostream>
class Foo {
public:
inline friend void bar(std::initializer_list<Foo> v) {
std::cout << "size = " << v.size() << std::endl;
}
};
void baz(std::initializer_list<Foo> v) {
std::cout << "size = " << v.size() << std::endl;
}
int main(){
Foo a;
//bar({a,a}); // error: use of undeclared identifier 'bar'
baz({a,a}); // works
return 0;
}
As seen above, an equivalent global function works just fine. Why does the above not work?
I'm using clang on OS X 10.10.
I believe that the problem is that the subexpression1 { a, a } does not really have a type, and as such it does not have associated types or namespaces which in turn means that ADL does not kick in. If you have a function in the global namespace, normal lookup will find it, and it will find that { a, a } can match the function call as the initializer for std::initializer_list<Foo>.
1 The syntax { a, a } is called braced-init-list and it is not really an expression (or subexpression) in the language.
When the compiler sees bar({a,a}), it doesn't know the type of the arguments, so it searches for bar in the global namespace (::), and nowhere else. If you changed that line to Foo{a,a}, then it knows the argument is a Foo, and so also searches the Foo class for functions.
I want to save lambda expressions variables (like in the fist code block). The problem is that then I use a classes (like the second code block) the compiler return me some errors. I don"t know how to fix it.
I hope somebody can help me and explain, why it's not working like this. Thanks.
First Code:
// variable for function pointer
void (*func)(int);
// default output function
void my_default(int x) {
cout << "x =" << "\t" << x << endl << endl;
}
int main() {
cout << "Test Programm\n\n";
// 1. Test - default output function
cout << "my_default\n";
func = &my_default;
func(5);
// 2. Test - special output function 2
cout << "my_func2\n";
func = [](int x) { cout << "x =" << " " << x << endl << endl; };
func(5);
return 0;
}
Second Code:
class test {
private:
// variable for function pointer
void (*func)(int);
// default output function
void my_default(int x) {
cout << "x =" << "\t" << x << endl << endl;
}
public:
void dummy(void) {
// 1. Test - default output function
cout << "my_default\n";
func = &my_default;
func(5);
// 2. Test - special output function 2
cout << "my_func2\n";
func = [](int x)->int{ cout << "x =" << " " << x << endl << endl; };
func(5);
}
};
// entry
int main() {
cout << "Test Programm\n\n";
test a;
a.dummy();
return 0;
}
Compiler:
pi#raspberrypi ~/dev/property $ gcc -std=c++0x -o test2 test2.cpp -lstdc++
test2.cpp: In member function ‘void test::dummy()’:
test2.cpp:491:17: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&test::my_default’ [-fpermissive]
test2.cpp:491:17: error: cannot convert ‘void (test::*)(int)’ to ‘void (*)(int)’ in assignment
test2.cpp:496:77: error: invalid user-defined conversion from ‘test::dummy()::<lambda(int)>’ to ‘void (*)(int)’ [-fpermissive]
test2.cpp:496:28: note: candidate is: test::dummy()::<lambda(int)>::operator int (*)(int)() const <near match>
test2.cpp:496:28: note: no known conversion for implicit ‘this’ parameter from ‘int (*)(int)’ to ‘void (*)(int)’
The problem is that member functions are not normal functions, they can't be assigned to a function pointer because the type in which they are member is part of their type.
Also, a member function needs to have an object to be called on, which will be the this inside the function code.
You have several solutions:
allow only functions which are member of your class
void (*MyClass::func)(int); // but you can use it only with members of the class
use std::function
typedef std::function<void(int)> func;
The solution 2 is the simplest as std::function is designed to work with anything that is callable with the same signature as the one in the template parammetters.
Also, it's the only solution that allows you to store closures(objects from lambdas).
See C++11 styled callbacks? for details.
class test {
private:
// variable for function pointer
std::function< void ( int )> func;
// default output function
void my_default(int x) {
cout << "x =" << "\t" << x << endl << endl;
}
public:
void dummy(void) {
// 1. Test - default output function
cout << "my_default\n";
func = std::bind(&test::my_default, this, std::placeholders::_1);
// or
func = [&]( int i ){ my_default( i ); };
func(5);
// 2. Test - special output function 2
cout << "my_func2\n";
func = [](int x)->int{ cout << "x =" << " " << x << endl << endl; };
func(5);
}
};
// entry
int main() {
cout << "Test Programm\n\n";
test a;
a.dummy();
return 0;
}
A member function is not like an ordinary function, in that there has to be an instance of the class available in order to invoke it (i.e., the object that will become *this). You can't make an ordinary function pointer variable point to a member function.
If you want to create a function pointer that can be called using any instance of the class, you need a member function pointer. You would write
void (test::*func)(int);
to declare it,
func = &test::my_default;
to assign it, and
(this->*func)(5);
to call it. Of course, now you can't make a member function pointer point to a lambda.
If on the other hand you want to bind this as the instance and create an ordinary function from a member function, well, you can't actually make an ordinary function pointer to it. Instead you'll want an std::function object,
std::function<void(int)> func;
bind as follows:
func = std::bind(&test::my_default, this, std::placeholders::_1);
and then call normally. std::function works with lambdas just like a function pointer would.
It appears that to test for const-ness, one must test the template-parameter, but to test for rvalue-ness, one must test an actual parameter. (This is using VC++ 2012.) This code illustrates what I mean:
#include <type_traits>
#include <string>
#include <iostream>
using namespace std;
template<class T>
void f(T& x) {
cout << "f() is_const<T> and is_const<decltype<x)>" << endl;
cout << is_const<T>::value << endl; // Prints 1 when arg is const
cout << is_const<decltype(x)>::value << endl; // Prints 0 when arg is const
}
template<class T>
void g(T&& x) {
cout << "g() is_const<T> and is_const<decltype<x)>" << endl;
cout << is_const<T>::value << endl; // Prints 0 when arg is const
cout << is_const<decltype(x)>::value << endl; // Prints 0 when arg is cons
cout << "g() is_rvalue_reference<T> and is_rvalue_reverence<decltype(x)>" <<endl;
cout << is_rvalue_reference<T>::value << endl; // Prints 0 when arg is rvlaue
cout << is_rvalue_reference<decltype(x)>::value << endl; // Prints 1 when arg is rvalue
}
int main()
{
const std::string str;
f(str); // const argument
cout << endl;
g(std::string("")); // rvalue argument
return 0;
}
I am struggling to understand why that is. Can someone explain, or point me to an article that explains it? If need be, I will dig into the C++11 standard. Anyone know the pertinent sections?
The reason is that you're misunderstanding things. x will never be const in any of those examples, simply because there are no const reference types (you can't change what a reference refers to anyways). In is_const<T> you're basically ignoring that you declared x as T&.
A similar misunderstanding is at work for the rvalue ref test. The T in T&& (which is called a universal reference, btw) will be deduced as U& when you pass an lvalue and as U when you pass an rvalue. When testing is_rvalue_reference<T>, you're ignoring again that you declared x as T&&. When testing is_const<T>, you didn't account for the fact that T will be a reference, which, as said above, can never be const.
The correct tests for g would be
std::is_const<typename std::remove_reference<T>::type>::value and
std::is_rvalue_reference<T&&>::value