Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8994343
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T23:24:37+00:00 2026-06-15T23:24:37+00:00

I have a following struct: struct Data { std::string firstMember; std::string secondMember; std::string thirdMember;

  • 0

I have a following struct:

struct Data
{
    std::string firstMember;
    std::string secondMember;
    std::string thirdMember;
};

I want to select one of the members by string name in constexpr manner, like

Data instance;
auto& member = getMember(instance, "firstMember"); 

getMember is constexpr function/struct/macros/whatever in question and expression should be (I want it to be) optimized into simple auto& member = instance.firstMember;. My desire here is to be able to call getMember from another constexpr function, which in turn are computing name of particular member –> some kind of compile time reflection.

I know, there is no reflection in C++, therefore it’s OK to register somehow (partially specialize? use some macros magic?) names of members of struct in question, like:

REGISTER_MEMBER(Data, "firstMember", firstMember);

All I want is to have that compile time optimization and do nothing in runtime. Is that possible in C++11 and how?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T23:24:38+00:00Added an answer on June 15, 2026 at 11:24 pm

    As noted in the comments, first take a look at BOOST_FUSION_ADAPT_STRUCT (and friends):

    #include <boost/fusion/include/adapt_struct.hpp>
    #include <string>
    
    struct Data
    {
        std::string firstMember;
        std::string secondMember;
        std::string thirdMember;
    };
    
    BOOST_FUSION_ADAPT_STRUCT(
        Data,
        (std::string, firstMember)
        (std::string, secondMember)
        (std::string, thirdMember)
        )
    

    This turns your Data structure into a sequence usable by Fusion:

    #include <boost/fusion/include/at_c.hpp>
    
    int main()
    {
        Data d = { "firstData", "secondData", "thirdData" };
    
        std::cout << boost::fusion::at_c<0>(d) << std::endl;
    }
    

    This prints "firstData". Change the index to refer to the members in order.

    There, now we can refer to members at compile-time using a number. But you wanted a name. Also noted in the comments, processing strings is a runtime feature…almost. C++11 gives us constexpr.

    It’s a bit tricky, but ultimately it looks like this:

    #include <boost/fusion/include/adapt_struct.hpp>
    #include <boost/preprocessor/cat.hpp>
    #include <boost/preprocessor/repetition/repeat.hpp>
    #include <boost/preprocessor/seq.hpp>
    #include <boost/preprocessor/tuple/elem.hpp>
    #include <stdexcept>
    
    // and repeat for BOOST_FUSION_ADAPT_TPL_STRUCT, etc...
    #define REFLECT_STRUCT(NAME, ATTRIBUTES)                                                \
            REFLECT_STRUCT_DETAIL(NAME,                                                     \
                                  ATTRIBUTES,                                               \
                                  BOOST_PP_SEQ_POP_FRONT(                                   \
                                    BOOST_PP_CAT(                                           \
                                        /* warning: uses fusion implementation details: */  \
                                        BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES,  \
                                        _END)))                                             \
    
    #define REFLECT_STRUCT_DETAIL(NAME, ATTRIBUTES, WRAPPEDATTRIBUTES)                  \
            BOOST_FUSION_ADAPT_STRUCT(NAME, ATTRIBUTES)                                 \
                                                                                        \
            namespace detail                                                            \
            {                                                                           \
                namespace BOOST_PP_CAT(reflect_, NAME)                                  \
                {                                                                       \
                    template <int N>                                                    \
                    struct member_name;                                                 \
                                                                                        \
                    BOOST_PP_SEQ_FOR_EACH_I(REFLECT_STRUCT_DETAIL_MEMBER_NAME,          \
                                            BOOST_PP_EMPTY,                             \
                                            WRAPPEDATTRIBUTES)                          \
                                                                                        \
                    template <int N>                                                    \
                    constexpr bool member_match_index(const std::size_t index,          \
                                                      const char* const str,            \
                                                      const std::size_t len)            \
                    {                                                                   \
                        return index == len ||                                          \
                               (member_name<N>::value()[index] == str[index]            \
                                && member_match_index<N>(index + 1, str, len));         \
                    }                                                                   \
                                                                                        \
                    template <int N>                                                    \
                    constexpr bool member_match(const char* const str,                  \
                                                const std::size_t len)                  \
                    {                                                                   \
                        return len == member_name<N>::value_length                      \
                               && member_match_index<N>(0, str, len);                   \
                    }                                                                   \
                                                                                        \
                    constexpr int find_member(const char* const str,                    \
                                              const std::size_t len)                    \
                    {                                                                   \
                        return BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(WRAPPEDATTRIBUTES),    \
                                               REFLECT_STRUCT_DETAIL_MEMBER_NAME_TEST,  \
                                               BOOST_PP_EMPTY)                          \
                               throw std::runtime_error("could not find "               \
                                                        BOOST_PP_STRINGIZE(NAME)        \
                                                        " member");                     \
                    }                                                                   \
                }                                                                       \
            }                                                                           \
                                                                                        \
            constexpr int BOOST_PP_CAT(indexof_, NAME)(const char* const str,           \
                                                       const std::size_t len)           \
            {                                                                           \
                return detail::BOOST_PP_CAT(reflect_, NAME)::find_member(str, len);     \
            }                                                                           \
                                                                                        \
            template <std::size_t N>                                                    \
            constexpr int BOOST_PP_CAT(indexof_, NAME)(const char (&str)[N])            \
            {                                                                           \
                return detail::BOOST_PP_CAT(reflect_, NAME)::find_member(&str[0], N);   \
            }
    
    #define REFLECT_STRUCT_DETAIL_EXTRACT_NAME(pair) \
            BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(1, pair))
    
    #define REFLECT_STRUCT_DETAIL_MEMBER_NAME(r, data, n, elem) \
            REFLECT_STRUCT_DETAIL_MEMBER_NAME_DETAIL(n, REFLECT_STRUCT_DETAIL_EXTRACT_NAME(elem))
    
    #define REFLECT_STRUCT_DETAIL_MEMBER_NAME_DETAIL(n, name)               \
            template <>                                                     \
            struct member_name<n>                                           \
            {                                                               \
                static constexpr std::size_t value_length = sizeof(name);   \
                typedef const char value_type[value_length];                \
                                                                            \
                static constexpr const value_type& value()                  \
                {                                                           \
                    return name;                                            \
                }                                                           \
            };
    
    #define REFLECT_STRUCT_DETAIL_MEMBER_NAME_TEST(z, n, text) \
            member_match<n>(str, len) ? n :
    

    It looks scary but its readable if you take the time to pick it apart.

    We have to introduce our own macros to give constant-expression access to the member names; most of the ugly comes from processing Boost.Preprocessor lists. Although Fusion does record the names during adaptation as well (see boost::fusion::extension::struct_member_name), they are not marked as constexpr so aren’t usable to us, unfortunately.

    This gives:

    #include <boost/fusion/include/at_c.hpp>
    #include <iostream>
    #include <string>
    
    struct Data
    {
        std::string firstMember;
        std::string secondMember;
        std::string thirdMember;
    };
    
    REFLECT_STRUCT(
        Data,
        (std::string, firstMember)
        (std::string, secondMember)
        (std::string, thirdMember)
        )
    
    // your desired code:
    // (note the use of at_c ensures this is evaluated at comple-time)
    #define GETMEMBER(data, member) boost::fusion::at_c<indexof_Data(member)>(data)
    
    int main()
    {
        Data d = { "firstData", "secondData", "thirdData" };
    
        std::cout << boost::fusion::at_c<indexof_Data("firstMember")>(d) << std::endl;
        std::cout << GETMEMBER(d, "secondMember") << std::endl;
        std::cout << GETMEMBER(d, "thirdMember") << std::endl;
        /* causes error: std::cout << GETMEMBER(d, "nonexistent_member") << std::endl; */
    }
    

    Which I think is close to what you were after.

    But keep in mind this may not all be necessary: Boost.Fusion may already have what you need. It lives in the area between pure compile-time stuff (Boost.MPL) and regular run-time stuff; adapt your struct and you can already do things like iterate over it (boost::fusion::for_each).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Suppose I have the following: struct Person { std::string mName; Birthday mBirthday; }; using
I have the following data container: struct Node { explicit Node(const std::vector<Data>& _data, const
I have the following problem: list.c struct nmlist_element_s { void *data; struct nmlist_element_s *next;
Suppose I have the following two data structures: std::vector<int> all_items; std::set<int> bad_items; The all_items
I have the following code: struct STFRandomTreeFunction { typedef double (*function_ptr)(const STFDataPoint& data, boost::unordered_map&
I have the following struct defining data returned from a collection of HID device
I have the following code: #include <map> #include <string> class policy1 { public: struct
I have the following code. Basically I want to initialize a std::array of non-POD
I have a std::vector<Word> data that is off of the struct below: struct Word
I have following struct to store my vertex data. struct Rz3DContourNode { float x;

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.