C++0 x試食:perfect forwarding(完璧転送)



コード1
#include <iostream>
#include <string>
using namespace std;

void inner(string&) {
	cout << "inner(string&)" << endl;
}

void inner(const string&) {
	cout << "inner(const string&)" << endl;
}

template <typename T> void outer(T& t) {
	inner(t);
}

template <typename T> void outer(const T& t) {
	inner(t);
}

string strange() {
	return "strange()";
}

const string charm() {
	return "charm()";
}

int main() {
string up("up");
const string down("down");

cout << "Directly calling inner()." << endl;
	inner(up);
	inner(down);
	inner(strange());
	inner(charm());

	cout << endl << "Calling outer()." << endl;
	outer(up);
	outer(down);
	outer(strange());
	outer(charm());
}

//Directly calling inner().
//inner(string&)
//inner(const string&)
//inner(const string&)
//inner(const string&)
//
//Calling outer().
//inner(string&)
//inner(const string&)
//inner(const string&)
//inner(const string&)

コード2
#include <iostream>
#include <ostream>
#include <string>
using namespace std;
 
template <typename T> struct Name;
 
template <> struct Name<string> {
    static const char * get() {
        return "string";
    }
};
 
template <> struct Name<const string> {
    static const char * get() {
        return "const string";
    }
};
 
template <> struct Name<string&> {
    static const char * get() {
        return "string&";
    }
};
 
template <> struct Name<const string&> {
    static const char * get() {
        return "const string&";
    }
};
 
template <> struct Name<string&&> {
    static const char * get() {
        return "string&&";
    }
};
 
template <> struct Name<const string&&> {
    static const char * get() {
        return "const string&&";
    }
};
 
template <typename T> void quark(T&& t) {
    cout << "t: " << t << endl;
    cout << "T: " << Name<T>::get() << endl;
    cout << "T&&: " << Name<T&&>::get() << endl;
    cout << endl;
}
 
string strange() {
    return "strange()";
}
 
const string charm() {
    return "charm()";
}
 
int main() {
    string up("up");
    const string down("down");
 
    quark(up);
    quark(down);
    quark(strange());
    quark(charm());
}

//t: up
//T: string&
//T&&: string&
//
//t: down
//T: const string&
//T&&: const string&
//
//t: strange()
//T: string
//T&&: string&&
//
//t: charm()
//T: const string
//T&&: const string&&

コード3
#include <iostream>
#include <string>
using namespace std;

template <typename T> struct Identity {
	typedef T type;
};

template <typename T> T&& Forward(typename Identity<T>::type& t) {
	return static_cast<T&&>(t);
}

void inner(string&) {
	cout << "inner(string&)" << endl;
}

void inner(const string&) {
	cout << "inner(const string&)" << endl;
}

void inner(string&&) {
	cout << "inner(string&&)" << endl;
}

void inner(const string&&) {
	cout << "inner(const string&&)" << endl;
}

template <typename T> void outer(T&& t) {
	inner(Forward<T>(t));
}

string strange() {
	return "strange()";
}

const string charm() {
	return "charm()";
}

int main() {
	string up("up");
	const string down("down");

	cout << "Directly calling inner()." << endl;
	inner(up);
	inner(down);
	inner(strange());
	inner(charm());

	cout << endl << "Calling outer()." << endl;
	outer(up);
	outer(down);
	outer(strange());
	outer(charm());
}

//Directly calling inner().
//inner(string&)
//inner(const string&)
//inner(string&&)
//inner(const string&&)
//
//Calling outer().
//inner(string&)
//inner(const string&)
//inner(string&&)
//inner(const string&&)