С++11, ибо цель — библиотека поддержки транслятора с матлаба в CUDA C++.
Здесь можно попробовать: https://onlinegdb.com/H1AnA0k18
Не могу добиться того, чтобы код работал для результатов возврата функции.
Что-то у меня плохо с пониманием lvalue/rvalue.
#include <iostream>
#include <type_traits>
#include <utility>
namespace std
{
template <typename T>
using remove_reference_t = typename remove_reference<T>::type;
template <typename T>
using remove_cv_t = typename remove_cv<T>::type;
template <typename T>
using remove_cvr = remove_reference<typename remove_cv<T>::type>;
template <typename T>
using remove_cvr_t = typename remove_cvr<T>::type;
}
namespace matlab
{
namespace details
{
using namespace ::std;
template <size_t I, typename T0, typename... T>
class tuple_impl
{
using this_type = tuple_impl<I, T0, T...>;
using base_type = tuple_impl<I - 1, T...>;
using value_type = std::remove_cvr_t<T0>;
const value_type c;
value_type& v;
base_type _i;
public:
tuple_impl() :
c({}), v(c)
{
}
tuple_impl(this_type &&that) :
_i(forward<base_type>(that._i)),
c(that.c), v(that.v)
{
}
tuple_impl(const this_type &that) :
_i(that._i),
c(that.c), v(that.v)
{
}
tuple_impl(T0 &arg0, T&&... args) :
_i(forward<T>(args)...),
c(arg0), v(arg0)
{
}
this_type &operator=(const this_type &that)
{
//for onlineGDB only, as it automatically shows only local varsconst auto &this_i = _i;
const auto &that_i = that._i;
_i = that._i;
v = that.c;
return *this;
}
};
template <typename T0>
class tuple_impl<0, T0>
{
using this_type = tuple_impl<0, T0>;
using value_type = remove_cvr_t<T0>;
const value_type c;
value_type& v;
public:
tuple_impl() :
c({}), v(c)
{
}
tuple_impl(this_type &&that) :
c(that.c), v(that.v)
{
}
tuple_impl(const this_type &that) :
c(that.c), v(that.v)
{
}
tuple_impl(value_type &arg0) :
c(arg0), v(arg0)
{
}
this_type &operator=(const this_type &that)
{
//for onlineGDB only, as it automatically shows only local varsconst auto &this_i = *this;
const auto &that_i = that;
v = that.c;
return *this;
}
};
}
template <typename... T>
class tuple
{
using this_type = tuple<T...>;
using impl = details::tuple_impl<sizeof...(T) - 1, T...>;
impl _i;
public:
tuple(this_type &&that) :
_i(std::forward<impl>(that._i))
{}
tuple(const this_type &that) :
_i(that._i)
{}
tuple(T&&... args) :
_i(std::forward<T>(args)...)
{}
// operator const this_type &() const
// {
// return const_cast<const this_type &>(*this);
// }
tuple& operator=(const tuple& that)
{
//for onlineGDB only, as it automatically shows only local varsauto &this_i = *this;
auto &that_i = that;
_i = that._i;
return *this;
}
};
using namespace std;
template <typename... T>
tuple<T...> to_tuple_works(T&& ...a)
{
return tuple<T...>(std::forward<T>(a)...);
}
template <typename... T>
tuple<std::remove_cvr_t<T>...> to_tuple_fails(T&& ...a)
{
return tuple<std::remove_cvr_t<T>...>(std::forward<T>(a)...);
}
char ch = 0;
int ii = 123;
float ff = 2.7;
static_assert(
std::is_same<
tuple<char, int, float>,
decltype(to_tuple_works(ch, ii, ff))>::value,
"fails"
);
}
matlab::tuple<int, float> foo_fails(int a, float b)
{
int aa = a * a;
float bb = b * b;
return matlab::to_tuple_fails(aa, bb);
}
float bar(int a, float b)
{
int aa = {};
float bb = {};
matlab::to_tuple_fails(aa, bb) = foo_fails(a, b);//decompose resultsreturn aa + bb;
}
int main()
{
using namespace std;
using namespace matlab;
int i0 = 123, i1 = 42;
float f0 = 2.7, f1 = 3.14;
cout << "Before" << endl;
cout << "i0: " << i0 << endl;
cout << "f0: " << f0 << endl;
cout << "i1: " << i1 << endl;
cout << "f1: " << f1 << endl << endl;
to_tuple_works(i0, f0) = to_tuple_works(i1, f1);
cout << "After" << endl;
cout << "i0: " << i0 << endl;
cout << "f0: " << f0 << endl;
cout << "i1: " << i1 << endl;
cout << "f1: " << f1 << endl << endl << endl;
i0 = 123;
cout << "Before exchange" << endl;
cout << "i0: " << i0 << endl;
cout << "i1: " << i1 << endl << endl;
to_tuple_works(i0, i1) = to_tuple_works(i1, i0);//exchange values python style
cout << "After exchange" << endl;
cout << "i0: " << i0 << endl;
cout << "i1: " << i1 << endl << endl;
auto r = bar(2, 3);
cout << "After bar" << endl;
cout << "r: " << r << endl;
return 0;
}
Здравствуйте, alexanderfedin, Вы писали:
A>С++11, ибо цель — библиотека поддержки транслятора с матлаба в CUDA C++. A>Здесь можно попробовать: https://onlinegdb.com/H1AnA0k18 A>Не могу добиться того, чтобы код работал для результатов возврата функции. A>Что-то у меня плохо с пониманием lvalue/rvalue.
Ага, плохо. Во фрагменте ниже функция to_tuple_works возвращает тупл ссылок: tuple <char&, int&, float&>.
Здравствуйте, rg45, Вы писали: R>Ага, плохо. Во фрагменте ниже функция to_tuple_works возвращает тупл ссылок: tuple <char&, int&, float&>.
Насчет этого я в курсе, вопрос был "что я делаю не так".
R>Ты бы разобрался в базовых вещах для начала, потом бы уже эмулировал.
Конечно же я разберусь. Часть процесса "разобраться" — это как раз задание вопросов более опытным товарищам.
Правда, товарищи эти должны быть не только более опытными, но и желающими поделиться сокровенным знанием.
Здравствуйте, alexanderfedin, Вы писали:
R>>Ты бы разобрался в базовых вещах для начала, потом бы уже эмулировал. A>Конечно же я разберусь. Часть процесса "разобраться" — это как раз задание вопросов более опытным товарищам. A>Правда, товарищи эти должны быть не только более опытными, но и желающими поделиться сокровенным знанием.
A>Вот, сделал: https://onlinegdb.com/Hy9aM4g1U
Извини за прямоту, но этот код показывает то, что ты даже не пытался разбираться. Извращение на извращении сидит и извращением погоняет. Простейший класс превратил в дичь какую-то.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: Эмулирую tuples такие, какими они сделаны в python, м
Здравствуйте, alexanderfedin, Вы писали:
A>Update: сделал: https://onlinegdb.com/Hy9aM4g1U
A>С++11, ибо цель — библиотека поддержки транслятора с матлаба в CUDA C++.
а почему нельзя сделать "exchange values python style" так?
int i0 = 1;
int i1 = 2;
std::tie(i0, i1) = std::make_tuple(i1, i0);
и что такое tuple в Matlab, чем он отличается от реализации в С++? Трудно читать код (особенно шаблонный), когда не понимаешь какую задачу он решает
Re[2]: Эмулирую tuples такие, какими они сделаны в python, м
Здравствуйте, sergii.p, Вы писали:
SP>а почему нельзя сделать "exchange values python style" так? SP>
SP> int i0 = 1;
SP> int i1 = 2;
SP> std::tie(i0, i1) = std::make_tuple(i1, i0);
SP>
SP>и что такое tuple в Matlab, чем он отличается от реализации в С++? Трудно читать код (особенно шаблонный), когда не понимаешь какую задачу он решает
Как я понял, главная его фишка как раз в том, что нет разделения на tuple и tie. И выражение to_tuple(i0, i1) = to_tuple(i1, i0), действительно выполняет обмен, подобно swap. Чтобы этого добиться, ему пришлось запихнуть в свой tuple одновременно и ссылку, и значение. Конструкторы сделал закрытыми, оставив только возможность конструирования через фабричные функции. Расплатой за это стало то, что теперь нельзя сделать простейшую инициализацию: auto t = to_tuple(1, 2); Потому что внутри объекта тут же возникают протухшие ссылки. Это, кстати, не такое уж редкое явление среди разработчиков, когда человек сосредотачивается на какой-нибудь фишечке и приносит ей в жертву остальной функционал.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали: R>Зачем делать сложным то, что проще простого.
Последний раз до этого я писал на C++ в 2002-м году.
Шаблоны были, но совсем не такого уровня.
R>Все придумано до нас: R>https://onlinegdb.com/Sk4YMvgJU
Спасибо!