Предположим, у меня есть некоторый код, который выглядит следующим образом
Convert.hpp
#pragma once
#include <cassert>
class Converter
{
public:
template <typename T>
static inline void to_type(const char* bytes, T& val);
static inline void to_int(const char* bytes, int& val);
};
#include "converter.inl"
Convert.inl
template <typename T>
void Converter::to_type(const char* bytes, T& value)
{
auto numberOfBytes = sizeof(T);
if (numberOfBytes == 8)
{
value = (T)(*(bytes + 3) << 40 | *(bytes + 3) << 32 | *(bytes + 3) << 24 | *(bytes + 2) << 16 | *(bytes + 1) << 8 | *bytes);
}
else if (numberOfBytes == 4)
{
value = (T)(*(bytes + 3) << 24 | *(bytes + 2) << 16 | *(bytes + 1) << 8 | *bytes);
}
else if (numberOfBytes == 2)
{
value = (T)(*(bytes + 1) << 8 | *bytes);
}
else {
assert(false);
}
}
void Converter::to_int(const char* bytes, int& value)
{
to_type(bytes, value);
}
Userofconverter.hpp
#pragma once
bool isConverterUsed(const char* bytes);
Userofconverter.cpp
#include <iostream>
#include "converter.hpp"
bool isConverterUsed(const char* bytes)
{
int myIntValue = 0;
Converter::to_type(bytes, myIntValue);
std::cout << "myIntValue: " << myIntValue << std::endl;
return true;
}
Anotheruserofconverter.hpp
#pragma once
bool isConverterUsedAgain(const char* bytes);
Anotheruserofconverter.cpp
#include <iostream>
#include "converter.hpp"
bool isConverterUsedAgain(const char* bytes)
{
int myIntValue = 0;
Converter::to_type(bytes, myIntValue);
std::cout << "myIntValue: " << myIntValue << std::endl;
return true;
}
Этот код ничего не делает, кроме как помогает мне проиллюстрировать мою проблему. Когда я компилирую с g++ (Ubuntu 8.3.0-6ubuntu1~18.04) 8.3.0
(в WSL, если это важно как-то), я получаю следующий вывод
$g++ main.cpp userofconverter.cpp anotheruserofconverter.cpp
In file included from converter.hpp:13,
from userofconverter.cpp:3:
converter.inl: In static member function ‘static void Converter::to_type(const char*, T&)’:
converter.inl:7:31: warning: left shift count >= width of type [-Wshift-count-overflow]
value = (T)(*(bytes + 3) << 40 | *(bytes + 3) << 32 | *(bytes + 3) << 24 | *(bytes + 2) << 16 | *(bytes + 1) << 8 | *bytes);
^~
converter.inl:7:52: warning: left shift count >= width of type [-Wshift-count-overflow]
value = (T)(*(bytes + 3) << 40 | *(bytes + 3) << 32 | *(bytes + 3) << 24 | *(bytes + 2) << 16 | *(bytes + 1) << 8 | *bytes);
^~
converter.inl: In instantiation of ‘static void Converter::to_type(const char*, T&) [with T = int]’:
converter.inl:24:23: required from here
converter.inl:7:28: warning: left shift count >= width of type [-Wshift-count-overflow]
value = (T)(*(bytes + 3) << 40 | *(bytes + 3) << 32 | *(bytes + 3) << 24 | *(bytes + 2) << 16 | *(bytes + 1) << 8 | *bytes);
~~~~~~~~~~~~~^~~~~
converter.inl:7:49: warning: left shift count >= width of type [-Wshift-count-overflow]
value = (T)(*(bytes + 3) << 40 | *(bytes + 3) << 32 | *(bytes + 3) << 24 | *(bytes + 2) << 16 | *(bytes + 1) << 8 | *bytes);
~~~~~~~~~~~~~^~~~~
In file included from converter.hpp:13,
from anotheruserofconverter.cpp:3:
converter.inl: In static member function ‘static void Converter::to_type(const char*, T&)’:
converter.inl:7:31: warning: left shift count >= width of type [-Wshift-count-overflow]
value = (T)(*(bytes + 3) << 40 | *(bytes + 3) << 32 | *(bytes + 3) << 24 | *(bytes + 2) << 16 | *(bytes + 1) << 8 | *bytes);
^~
converter.inl:7:52: warning: left shift count >= width of type [-Wshift-count-overflow]
value = (T)(*(bytes + 3) << 40 | *(bytes + 3) << 32 | *(bytes + 3) << 24 | *(bytes + 2) << 16 | *(bytes + 1) << 8 | *bytes);
^~
converter.inl: In instantiation of ‘static void Converter::to_type(const char*, T&) [with T = int]’:
converter.inl:24:23: required from here
converter.inl:7:28: warning: left shift count >= width of type [-Wshift-count-overflow]
value = (T)(*(bytes + 3) << 40 | *(bytes + 3) << 32 | *(bytes + 3) << 24 | *(bytes + 2) << 16 | *(bytes + 1) << 8 | *bytes);
~~~~~~~~~~~~~^~~~~
converter.inl:7:49: warning: left shift count >= width of type [-Wshift-count-overflow]
value = (T)(*(bytes + 3) << 40 | *(bytes + 3) << 32 | *(bytes + 3) << 24 | *(bytes + 2) << 16 | *(bytes + 1) << 8 | *bytes);
~~~~~~~~~~~~~^~~~~
В выводе компиляции я вижу дважды это сообщение In instantiation of ‘static void Converter::to_type(const char*, T&) [with T = int]’
- Означает ли это, что функция Converter :: to_type фактически создается два раза?
- Если так, есть ли способ избежать множественных экземпляров?