Рассмотрим следующий код:C++ странно шаблон специализации на внутренней переменной
#include <iostream>
#include <typeinfo>
#include <cstring>
#include <cstdlib>
static void random_string(char *s, const int len)
{
static const char alphanum[] =
""
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < len; ++i)
s[ i ] = alphanum[ rand() % (sizeof(alphanum) - 1) ];
s[ len ] = 0;
}
template< typename Type, int Length >
void info(Type (&var)[ Length ])
{
std::cout << "-> Type is " << typeid(var).name() << std::endl;
std::cout << "-> Pointer size: " << sizeof(Type *) << std::endl;
std::cout << "-> Number of elements: " << Length << std::endl;
std::cout << "-> Size of each element: " << sizeof(Type) << std::endl;
std::cout << "-> contents: \"" << var << "\"." << std::endl;
}
template< typename SourceType, int SourceLength, typename TargetType, int TargetLength >
void func(TargetType (&target)[ TargetLength ])
{
SourceType source[ SourceLength ];
random_string((char *)source, SourceLength - 1);
std::cout << "-= source =-" << std::endl;
info(source);
std::cout << "-= target =-" << std::endl;
info(target);
std::memcpy(target, source,
(SourceLength < TargetLength ? SourceLength : TargetLength));
}
int main()
{
typedef char char16[ 16 ];
typedef char char64[ 64 ];
char16 c16 = "16 bytes chars.";
char64 c64 = "64 bytes chars. There's a lot more room here...";
std::cout << "c16 = \"" << c16 << "\"." << std::endl;
func< char64, sizeof(char64) >(c16);
std::cout << "c16 = \"" << c16 << "\"." << std::endl;
std::cout << "c64 = \"" << c64 << "\"." << std::endl;
func< char16, sizeof(char16) >(c64);
std::cout << "c64 = \"" << c64 << "\"." << std::endl;
return 0;
}
И этот выход:
> g++ -Wall -g3 array_conversions.cpp -o array_conversions
> ./array_inner_type
c16 = "16 bytes chars.".
-= source =-
-> Type is A64_A64_c
-> Pointer size: 8
-> Number of elements: 64
-> Size of each element: 64
-> contents: "0x7fff8b913380".
-= target =-
-> Type is A16_c
-> Pointer size: 8
-> Number of elements: 16
-> Size of each element: 1
-> contents: "16 bytes chars.".
c16 = "fa37JncCHryDsbza".
c64 = "64 bytes chars. There's a lot more room here...".
-= source =-
-> Type is A16_A16_c
-> Pointer size: 8
-> Number of elements: 16
-> Size of each element: 16
-> contents: "0x7fff8b914280".
-= target =-
-> Type is A64_c
-> Pointer size: 8
-> Number of elements: 64
-> Size of each element: 1
-> contents: "64 bytes chars. There's a lot more room here...".
c64 = "Z2nOXpPIhMFSv8k".
Как видим, понимание того, что SourceType source[ SourceLength ]
для меня и НКУ не является тоже самое.
Я ожидал SourceType source[ SourceLength ]
быть типа char64
(«A64_c»), но GCC говорит мне, что это «A64_A64_c» и действует, как если бы это был массив char64
или что-то подобное.
Странно это происходит только с местной переменной source
. Функциональный параметр target
правильно интерпретируется.
Что мне не хватает? Есть ли недоразумения в моем коде?
Я чувствую, что эта проблема связана с этим C++ Template argument changes Reference to Pointer, отправленная мной почти год назад, но этот вопрос не имел ответа, так что теперь я прошу вас, пожалуйста, за любую помощь.
Действительно спасибо.
Вы написали слишком много кода, пожалуйста, будьте более краткими, удалив из кода неинтересные части. – vulkanino