Imagine a matrix type, implemented as a B.TE any and a series of structs representing ordinary matrices, etc. It has a set of operations, say, transpose, etc. transpose should return a matrix. Can this be implemented in B.TE? Something like:
BOOST_TYPE_ERASURE_FREE(transpose);
struct ordinary_matrix_impl {};
using matrix =
any<mpl::vector<copy_constructible<>, has_transpose<matrix(_self&)>>>;
auto transpose(ordinary_matrix_impl&) {
// ...
return matrix(ordinary_matrix_impl(/*...*/));
}
But the using matrix = ...
doesn't compile (error: 'matrix' was not declared in this scope).
Is there a solution?
Imagine a matrix type, implemented as a B.TE any and a series of structs representing ordinary matrices, etc. It has a set of operations, say, transpose, etc. transpose should return a matrix. Can this be implemented in B.TE? Something like:
BOOST_TYPE_ERASURE_FREE(transpose);
struct ordinary_matrix_impl {};
using matrix =
any<mpl::vector<copy_constructible<>, has_transpose<matrix(_self&)>>>;
auto transpose(ordinary_matrix_impl&) {
// ...
return matrix(ordinary_matrix_impl(/*...*/));
}
But the using matrix = ...
doesn't compile (error: 'matrix' was not declared in this scope).
Is there a solution?
Share Improve this question edited Mar 28 at 14:16 yorel asked Mar 28 at 12:29 yorelyorel 3411 silver badge8 bronze badges 2 |2 Answers
Reset to default 0Looks like you're referencing matrix
in its own definition.
Here's what I'd write:
Live On Coliru
#include <boost/mpl/vector.hpp>
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/constructible.hpp>
#include <boost/type_erasure/free.hpp>
#include <fmt/ranges.h>
struct ordinary_matrix_impl {
// friend auto transpose(ordinary_matrix_impl/*const&*/ m) { return /*TODO*/ m; };
};
BOOST_TYPE_ERASURE_FREE(transpose)
namespace te = boost::type_erasure;
namespace mpl = boost::mpl;
using matrix = te::any<mpl::vector<te::copy_constructible<>,
has_transpose<te::_self(te::_self const&)>>>;
auto transpose(ordinary_matrix_impl /*const&*/ m) { return m; /* TODO */ }
int main() {
matrix a = ordinary_matrix_impl{};
matrix b = transpose(a);
}
Solved it. Just wrap the any in a struct (Compiler Explorer):
#include <boost/mpl/vector.hpp>
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/free.hpp>
#include <iostream>
namespace mpl = boost::mpl;
using namespace boost::type_erasure;
BOOST_TYPE_ERASURE_FREE(transpose);
struct ordinary_matrix_impl {};
struct symmetric_matrix_impl {};
struct matrix {
any<mpl::vector<copy_constructible<>, has_transpose<matrix(_self&)>>> impl;
};
auto transpose(matrix m) {
return transpose(m.impl);
}
auto transpose(ordinary_matrix_impl& m) {
std::cout << "make a new ordinary matrix\n";
return matrix{ordinary_matrix_impl()};
}
auto transpose(symmetric_matrix_impl& m) {
std::cout << "make a new diagonal matrix\n";
return matrix{m};
}
auto main() -> int {
{
matrix m{ordinary_matrix_impl()};
auto t = transpose(m);
}
{
matrix m{symmetric_matrix_impl()};
auto t = transpose(m);
}
return 0;
}
using foo = foo*
. – yorel Commented Mar 28 at 13:45