Я работал над этим в течение некоторого времени, и нашел это Q / A как хороший ответ о том, как я могу хранить кортеж.Теперь я пытаюсь использовать шаблон функции, который сгенерирует этот класс, и ключевое слово auto для создания экземпляров этого объекта.Я не получаю никаких ошибок компилятора;пока он не генерирует никаких данных, и я не могу понять, где я ошибаюсь, однако, мой ostream<<()
генерирует ошибки компилятора с жалобами на std::get
Вот мой класс и несколько способово том, как я пытаюсь его использовать.
#include <algorithm>
#include <iostream>
#include <tuple>
template<class... T>
class expression_t {
public:
std::tuple<T...> rhs;
std::size_t size = sizeof...(T);
template<class... Args>
expression_t(Args&& ...args) : rhs( std::forward<Args>(args)... ){}
std::tuple<T...> operator()() {
return hrs;
}
};
template<typename... Args>
expression_t<Args...> expression(Args... args) {
expression_t<Args...> expr(args...);
return expr;
}
template<typename... Args>
std::ostream& operator<< (std::ostream& os, const expression_t<Args...>& expr) {
for (std::size_t n = 0; n < expr.size; n++ ) {
if ( std::get<n>(expr.rhs) == '+' || std::get<n>(expr.rhs) == '-' ||
std::get<n>(expr.rhs) == '*' || std::get<n>(expr.rhs) == '/' ||
std::get<n>(expr.rhs) == '%')
os << ' ' << std::get<n>(expr.rhs) << ' ';
os << std::get<n>(expr.rhs);
}
os << '\n';
return os;
}
int main() {
double x = 0;
// example: 4x^2 + 2x
auto expr = expression( 4, x, '^', 2, '+', 2, x );
// try to print a single element from expr's tuple member
auto t = expr(); // using operator()
std::cout << std::get<2>(t); // compiles and runs but does not work
// try to print out the expression
std::cout << expr; // the ostream<<() operator fails to compile
// it is complaining about `std::get` with no matching overloaded function found
// with MSVC error C2672
return 0;
}
Редактировать
Я воспользовался советом Игоря и попытался использовать cppreference'sнайденный пример здесь и это то, что я придумал для моего operator<<()
.
template<class Ch, class Tr, class Tuple, std::size_t... Is>
void print_expression_tuple_impl(std::basic_ostream<Ch, Tr>& os, const Tuple& t, std::index_sequence<Is...>) {
if ( (std::get<Is>(t) == '+') ||
(std::get<Is>(t) == '-') ||
(std::get<Is>(t) == '*') ||
(std::get<Is>(t) == '/') ||
(std::get<Is>(t) == '%') )
os << " " << std::get<Is>(t) << " ";
os << std::get<Is>(t);
}
template<class Ch, class Tr, class... Args>
auto& operator<<(std::basic_ostream<Ch,Tr>& os, const std::tuple<Args...>& t) {
print_expression_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os;
}
template<class... Args>
std::ostream& operator<<(std::ostream& os, const expression_t<Args...>& expr) {
return os << expr.rhs << '\n';
}
Это жалуется на то, что Is
необходимо расширить, хорошо, поэтому я пытаюсь расширитьэто в функции print...
, и я попытался поместить оператор ...
в нескольких местах, и, похоже, ничего не компилируется.Я не уверен, как расширить Is
в этом контексте, или я могу даже использовать выражения свертки.