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?
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
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.