std::integral_constant won't compile?

后端 未结 2 1406
执笔经年
执笔经年 2021-01-16 18:16

I want to make integral constant from char* and \"kernel32.dll\", but failed always. The following are my failed attempts, anyone can show me the correct usage?



        
相关标签:
2条回答
  • 2021-01-16 18:49

    The template parameter type in your code, currently instantiated with std::integral_constant<>, is used only to access ::value static member, so you can replace it with any other type defining value member, just like shown below:

    #include <iostream>
    
    template <typename T>
    void print()
    {
        std::cout << (T::value) << std::endl;
    }
    
    struct X
    {
        static const char* value;
    };
    
    const char* X::value = "ABC";
    
    int main()
    {
        print<X>();
    }
    

    That is, just put X in place of std::integral_constant<>.

    function_t ptrFunc
        = delegate<void, Class, int>
              ::adapter<&Class::print, X /*here!*/>
              ::invoke_no_fwd;
    

    Live demo link.


    UPDATE 1

    If you want to specify the string's content inline, within template instantiation, the below code will do the trick:

    template <char... Chars>
    struct MyString
    {
        static constexpr char value[] = { Chars..., '\0' };
    };
    
    template <char... Chars>
    constexpr char MyString<Chars...>::value[];
    
    // MyString<'A', 'B', 'C'>::value is same as const char[4] = { "ABC" };
    
    function_t ptrFunc
        = delegate<void, Class, int>
              ::adapter<&Class::print, MyString<'A', 'B', 'C'>>
              ::invoke_no_fwd;
    

    Another live demo link.


    UPDATE 2

    If you are tired of typing MyString<'k','e','r','n','e','l','3','2','.','d','l','l'> you can instead expand a raw string like "kernel32.dll" into comma-separated characters list compliant with MyString<char...> template, using below macro (that for simplicity is limited to 32-character-long strings):

    #include <iostream>
    
    #define STR_1(S,I) (I < sizeof(S) ? S[I] : '\0')
    #define STR_2(S,I) STR_1(S,I), STR_1(S,I+1)
    #define STR_4(S,I) STR_2(S,I), STR_2(S,I+2)
    #define STR_8(S,I) STR_4(S,I), STR_4(S,I+4)
    #define STR_16(S,I) STR_8(S,I), STR_8(S,I+8)
    #define STR_32(S,I) STR_16(S,I), STR_16(S,I+16)
    #define STR(S) STR_32(S,0)
    
    template <char... Chars>
    struct MyString
    {
        static constexpr char value[] = { Chars..., '\0' };
    };
    
    template <char... Chars>
    constexpr char MyString<Chars...>::value[];
    
    int main()
    {
        std::cout << MyString<STR("kernel32.dll")>::value << std::endl;
    }
    

    Yet another live demo link

    0 讨论(0)
  • 2021-01-16 18:59

    You may declare a static const char* and use it in std::integral_constant, something like:

    static constexpr const char money[] = "money";
    
    int main()
    {
        typedef void(*function_t)(int);
        function_t ptrFunc =
            delegate<void, Class, int>
                ::adapter<
                    &Class::print,
                    std::integral_constant<const char*, money> >::invoke_no_fwd;
        auto type = delegate<void, Class, int>::
            adapter<&Class::print, std::integral_constant<const char*, money>>::invoke_no_fwd;
        ptrFunc(-42); // 0
        type(0); // 42
    
        return 0;
    }
    

    Live example

    You may use something like in Aligning static string literals to allow to write the literal string in std::integral_constant with a Macro.

    0 讨论(0)
提交回复
热议问题