Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

template for expansion statements usage #121

Open
githubuser6000 opened this issue Nov 26, 2024 · 2 comments
Open

template for expansion statements usage #121

githubuser6000 opened this issue Nov 26, 2024 · 2 comments

Comments

@githubuser6000
Copy link

Is your feature request related to a problem? Please describe.

I was trying to use the template for syntax, but it wasn't clear to me from the proposal how and in what contexts it is supposed to work.

I am trying this example ...

struct test {
    int one;
    int two;
    int three;
};

template<typename T>
consteval void template_for_expansion_stmt() {
    template for(constexpr auto member : std::meta::define_static_array(
                                 std::meta::nonstatic_data_members_of(^T)))
    {
        // ...
    }
}

int main() {
    template_for_expansion_stmt<test>();
}

I get this error

clang++ -std=c++26 -stdlib=libc++ -freflection -fparameter-reflection -fconsteval-blocks -fexpansion-statements main.cxx -o main
src/main.cxx:43:42: error: cannot decompose private member '__data_' of 'std::span<const meta::info>'
   43 |     template for(constexpr auto member : std::meta::define_static_array(
      |                                          ^
src/main.cxx:51:5: note: in instantiation of function template specialization 'template_for_expansion_stmt<test>' requested here
   51 |     template_for_expansion_stmt<test>();
      |     ^
/home/user/.local/llvm-reflect/bin/../include/c++/v1/span:568:11: note: declared private here
  568 |   pointer __data_;
      |           ^
src/main.cxx:43:42: error: cannot decompose private member '__size_' of 'std::span<const meta::info>'
   43 |     template for(constexpr auto member : std::meta::define_static_array(
      |                                          ^
/home/user/.local/llvm-reflect/bin/../include/c++/v1/span:569:13: note: declared private here
  569 |   size_type __size_;
      |             ^
2 errors generated.

Thank you for the help!

@Tsche
Copy link

Tsche commented Feb 7, 2025

From a quick look at the code it seems to me that expansion statements are only implemented over init-lists and decomposable types. std::vector is not decomposable because of its private members (that's the error you're seeing). The same is the case for std::span<T>, which is why the workaround with define_static_array didn't work either.

A simple workaround would be something along the lines of

template <typename T, T... Vs>
constexpr inline T static_array[sizeof...(Vs)] = {Vs...};

consteval auto intern(std::ranges::input_range auto&& r){
    std::vector args = {^^std::ranges::range_value_t<decltype(r)>};
    for (auto e : r) {
        args.push_back(std::meta::reflect_value(e));
    }
    return substitute(^^static_array, args);
}

struct Foo {
    int a;
    int b;
};

int main(){
    consteval {
        // error: constexpr variable '[, , , , , ]' must be initialized by a constant expression
        // error: cannot decompose private member '__begin_' of 'std::vector<meta::info>'
        //template for (constexpr auto member : nonstatic_data_members_of(^^Foo)) { /* ... */ }

        template for (constexpr auto member : [:intern(nonstatic_data_members_of(^^Foo)):]) { 
            /* ... */
        }
    }
}

run on compiler explorer

@githubuser6000
Copy link
Author

Oh that's pretty neat, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants