A standard way for getting variable name at compile time

后端 未结 3 751
情话喂你
情话喂你 2021-02-15 14:13

Is there some way in C++11 or higher to achieve a similar behavior to:

int some_int;
std::string x=variable_name::value; //Theoretical code 
std:         


        
3条回答
  •  陌清茗
    陌清茗 (楼主)
    2021-02-15 15:14

    You ask:

    Is there some way in C++11 or higher to achieve a similar behavior to:

    int some_int;
    std::string x=type_name::value; //Theoretical code 
    std::cout << x;
    

    Result should be:

    some_int

    Yes, you can just use the preprocessor's stringizing operator #:

    #include 
    
    #define NAME_OF( v ) #v
    
    using namespace std;
    auto main() -> int
    {
        int some_int;
         //std::string x=type_name::value; //Theoretical code 
        auto x = NAME_OF( some_int );
        (void) some_int;
        cout << x << endl;
    }
    

    If you're asking for something different, then please post a new question since this one has now been answered (amending the question would invalidate this answer).


    As an example real world usage, here's macro to pass a variable and its name to a test function:

    #define TEST( v ) test( v, #v )
    

    If you want a compile time check that the name in question is a variable or type name, then you can simply apply sizeof, e.g. in a comma expression:

    #define NAME_OF( v ) (sizeof(v), #v)
    

    The difference between having sizeof or not, is whether this is guaranteed to be done purely at compile time, versus possibly generating code to also do something at run time.

    To avoid a possible warning you can add a pseudo-cast to void:

    #define NAME_OF( v ) ((void) sizeof(v), #v)
    

    And to make this work also for a function name you can add a typeid:

    #define NAME_OF( name ) ((void) sizeof(typeid(name)), #name)
    

    Complete example:

    #include 
    
    #define NAME_OF( name ) ((void) sizeof(typeid(name)), #name)
    
    void foo() {}
    
    #include 
    using namespace std;
    auto main() -> int
    {
        int some_int;
        (void) some_int;
         //std::string x=type_name::value; //Theoretical code 
        auto v = NAME_OF( some_int );
        auto t = NAME_OF( int );
        auto f = NAME_OF( foo );
        #ifdef TEST_CHECKING
            (void) NAME_OF( not_defined );
        #endif
        cout << v << ' ' << t << ' ' << f << endl;
    }
    

    The checking is not 100% perfect, though, because it's still possible to pass a function invocation to the NAME_OF macro.

提交回复
热议问题