最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Boost.TypeErasure `any` with a concept returning the same `any`? - Stack Overflow

programmeradmin2浏览0评论

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
  • "doesn't compile." is there an error message? – 463035818_is_not_an_ai Commented Mar 28 at 12:31
  • I added the error message, but it is quite obvious that this cannot compile. It's like saying using foo = foo*. – yorel Commented Mar 28 at 13:45
Add a comment  | 

2 Answers 2

Reset to default 0

Looks 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;
}
发布评论

评论列表(0)

  1. 暂无评论