Я хочу сделать интегральную константу из char * и "kernel32.dll", но не всегда. Следующие мои неудачные попытки, каждый может показать мне правильное использование?
error 1: cout << std::integral_constant<const char*, "kernel32.dll">::value << endl;
error 2: cout << std::integral_constant<char*, "kernel32.dll">::value << endl;
error 3: cout << std::integral_constant<char[], "kernel32.dll">::value << endl;
error 4: cout << cout << std::integral_constant<char*, static_cast<char*>("kernel32.dll")>::value << endl;
вышеупомянутые 4 оператора имеют одинаковую ошибку:
Console.cpp(181): error C2762: 'std::integral_constant' : invalid expression as a template argument for '_Val'
1> D:\Programfiles\Visual Studio 2013\VC\include\xtr1common(35) : see declaration of 'std::integral_constant'
1>Console.cpp(181): error C2955: 'std::integral_constant' : use of class template requires template argument list
1> D:\Programfiles\Visual Studio 2013\VC\include\xtr1common(35) : see declaration of 'std::integral_constant'
1>Console.cpp(181): warning C4552: '<<' : operator has no effect; expected operator with side-effect
Обновить:
std::integral_constant<std::string, "abc">::value
также не будет компилироваться.
окончательное обновление
Вот мой сценарий, я делаю простую демонстрацию, чтобы продемонстрировать свою цель:
#include <iostream>
#include <type_traits>
template< typename R, typename C, typename... Args>
class delegate
{
public:
template<R(C::*F)(Args...), typename ... Ts>
struct adapter
{
static R invoke_no_fwd(Args... args)
{
C t((Ts::value)...);
return (t.*F)(args...);
}
};
};
class Class
{
public:
Class(const char* psz) {
std::cout << psz << std::endl;
}
void print(int v)
{
std::cout << "Class: " << v << std::endl;
}
};
int main()
{
typedef void(*function_t)(int);
function_t ptrFunc = delegate<void, Class, int>::adapter<&Class::print, std::integral_constant<char*, "money"> >::invoke_no_fwd;
auto type = delegate<void, Class, int>::adapter<&Class::print, std::integral_constant<int, 42>>::invoke_no_fwd;
ptrFunc(-42); // 0
type(0); // 42
return 0;
}
Тип шаблона параметра в коде, в настоящее время экземпляра с std::integral_constant<>
, используются только для доступа ::value
статического члена, так что вы можете заменить его на любой другой тип определения value
элемента, так же, как показано ниже:
#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>();
}
То есть просто положите X
вместо std::integral_constant<>
.
function_t ptrFunc
= delegate<void, Class, int>
::adapter<&Class::print, X /*here!*/>
::invoke_no_fwd;
ОБНОВЛЕНИЕ 1
Если вы хотите указать строковое содержимое inline, в рамках создания шаблона, приведенный ниже код выполнит трюк:
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;
Еще одна живая демонстрационная ссылка.
ОБНОВЛЕНИЕ 2
Если вы устали печатать MyString<'k','e','r','n','e','l','3','2','.','d','l','l'>
вместо этого вы можете расширить исходную строку, такую как "kernel32.dll"
в список разделенных запятыми символов, соответствующий шаблону MyString<char...>
, используя ниже макрос (который для простоты ограничивается 32-символьным символом, длинные строки):
#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;
}
std::integral_constant
integra_constant, как ты думаешь, что это? это static
значение
Вы можете объявить static const char*
и использовать его в std::integral_constant
, например:
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;
}
Вы можете использовать что-то вроде " Выравнивание статических строковых литералов", чтобы разрешить запись литеральной строки в std::integral_constant
с помощью макроса.