Здравствуйте, Кодт, Вы писали:
К>Различать значения и ссылки очень, очень мучительно.
К>(Говорят, в C++0x есть rvalue references, но я в этом скорее осло, чем копенгаген).
както в таком вот акцепте...
#include <iostream>
#include <string>
#include <typeinfo>
#include <cassert>
#include <malloc.h>
#include <cxxabi.h>
#include <boost/type_traits/is_reference.hpp>
using namespace std;
template <typename T>
std::string type_name(const T&)
{
const char* const name = typeid(T).name();
// Try to demangle name using gcc API (of couse if current compiler is gcc)
int status;
char* demangled_name = abi::__cxa_demangle(name, 0, 0, &status);
if (!status)
{
std::string name = demangled_name;
free(demangled_name);
return name;
}
assert(!"How is that possible? Fail on demangle name produced by itself??");
return name;
}
class TFubar {};
class TFubarA: public TFubar {};
class TFubarB: public TFubar {};
TFubarA GetFubarA() { return TFubarA(); }
const TFubar& GetFubarRefB() { static TFubarB f; return f; }
template<typename FOOBAR>
class TFubarHolder
{
FOOBAR m_f;
public:
explicit TFubarHolder(FOOBAR f): m_f(f) {}
};
template <typename FOOBAR>
class TFubarHolder<const FOOBAR&>
{
const FOOBAR& m_f;
public:
explicit TFubarHolder(const FOOBAR& f): m_f(f) {}
};
template <typename FOOBAR>
TFubarHolder<FOOBAR> Hold(FOOBAR&& f)
{
return TFubarHolder<FOOBAR>(f);
}
int main()
{
// должно вернуть TFubarHolder<TFubarA>
auto f1 = Hold(GetFubarA());
cout << type_name(f1) << endl;
// должно вернуть TFubarHolder<const TFubarB&> или TFubarHolder<const TFubar&>
auto f2 = Hold(GetFubarRefB());
cout << type_name(f2) << endl;
return 0;
}
zaufi /work/tests $ g++ -std=gnu++0x -o vr vr.cc
zaufi /work/tests $ ./vr
TFubarHolder<TFubarA>
TFubarHolder<TFubar const&>
zaufi /work/tests $ g++ --version
g++ (Gentoo 4.4.2 p1.0) 4.4.2
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.