Supposons que j'ai un tableau d'entiers qui peut grossir avec le temps. Pour économiser de la mémoire, j'ai construit une classe qui prend une valeur maximale qui sera stockée dans le tableau, et la convertit en l'un des types entiers suivants: uint8_t
, uint16_t
, uint32_t
, uint64_t
.La sélection du type d'int avec la méta-programmation génère une erreur
Le code:
#include <limits>
#include <cstdint>
template <uint64_t MAX_VAL>
class SELECTOR_INT
{
private:
using enum_type = uint64_t;
static enum : enum_type { success_8 = 1, success_16 = 2, success_32 = 3, success_64 = 4 };
static enum : enum_type { failure_8 = 11, failure_16 = 12, failure_32 = 13, failure_64 = 14 };
#define TYPE_MAX(_TYPE) static_cast<enum_type>(std::numeric_limits<_TYPE>::max())
static enum : enum_type { result_8 = ( (MAX_VAL <= TYPE_MAX(uint8_t))) ? success_8 : failure_8 };
static enum : enum_type { result_16 = ((MAX_VAL > TYPE_MAX(uint8_t)) && (MAX_VAL <= TYPE_MAX(uint16_t))) ? success_16 : failure_16 };
static enum : enum_type { result_32 = ((MAX_VAL > TYPE_MAX(uint16_t)) && (MAX_VAL <= TYPE_MAX(uint32_t))) ? success_32 : failure_32 };
static enum : enum_type { result_64 = ((MAX_VAL > TYPE_MAX(uint32_t)) ) ? success_64 : failure_64 };
#undef TYPE_MAX
#define MIN(_LOP, _ROP) ((_LOP < _ROP) ? _LOP : _ROP)
static enum : enum_type { RESULT = MIN(result_8, MIN(result_16, MIN(result_32, MIN(result_32, result_64)))) };
#undef MIN
private:
template <enum_type num>
struct CHOOSED;
template <> struct CHOOSED <success_8 > { using TYPE = typename uint8_t; }; // Line 162
template <> struct CHOOSED <success_16> { using TYPE = typename uint16_t; }; // Line 163
template <> struct CHOOSED <success_32> { using TYPE = typename uint32_t; }; // Line 164
template <> struct CHOOSED <success_64> { using TYPE = typename uint64_t; }; // Line 165
public:
using TYPE = CHOOSED<RESULT>::TYPE;
};
using int_type = SELECTOR_INT<200>::TYPE;
int main()
{
int_type test_variable = 0;
return 0;
}
malheureusement, j'ai foiré quelque chose parce que je reçois les erreurs suivantes:
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(163): error C2766: explicit specialization; 'SELECTOR_INT<MAX_VAL>::CHOOSED<>' has already been defined
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(162): note: see previous definition of 'CHOOSED<, ?? :: ?? :: ?? ::<unnamed-enum-success_8> >'
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(171): note: see reference to class template instantiation 'SELECTOR_INT<MAX_VAL>' being compiled
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(164): error C2766: explicit specialization; 'SELECTOR_INT<MAX_VAL>::CHOOSED<>' has already been defined
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(162): note: see previous definition of 'CHOOSED<, ?? :: ?? :: ?? ::<unnamed-enum-success_8> >'
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(165): error C2766: explicit specialization; 'SELECTOR_INT<MAX_VAL>::CHOOSED<>' has already been defined
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(162): note: see previous definition of 'CHOOSED<, ?? :: ?? :: ?? ::<unnamed-enum-success_8> >'
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(169): error C2027: use of undefined type 'SELECTOR_INT<4>::CHOOSED<0>'
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(169): note: see declaration of 'SELECTOR_INT<4>::CHOOSED<0>'
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(187): note: see reference to class template instantiation 'SELECTOR_INT<4>' being compiled
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(169): error C2061: syntax error: identifier 'TYPE'
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(169): error C2238: unexpected token(s) preceding ';'
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(187): error C2039: 'TYPE': is not a member of 'SELECTOR_INT<4>'
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(187): note: see declaration of 'SELECTOR_INT<4>'
1>D:/Dev/visual_studio/nevada_test_site/source/workspace/internship/hamiltonian/start.cu(187): error C2061: syntax error: identifier 'TYPE'
Question:
Comment puis-je résoudre ce problème?
'static enum'? – LogicStuff
Je pensais que c'était le cas. Je crois (mais je ne suis pas sûr) que l'erreur signale que j'ai créé plusieurs instances de cette classe. Si je supprime la déclaration "template" de la classe 'SELECTOR_INT' tout fonctionne correctement. par exemple. 'erreur C2766: spécialisation explicite; 'SELECTOR_INT :: CHOOSED <>' a déjà été défini ' –
cukier9a7b5
Eh bien, un [mcve] aiderait, ou au moins dire quelle ligne est ce que dans votre question. Cela réglerait votre question. – Yakk