Pergunta

O código abaixo compila, mas tem um comportamento diferente para o tipo de char do que para os tipos int.

Em particular

   cout << getIsTrue< isX<int8>::ikIsX  >() << endl;
   cout << getIsTrue< isX<uint8>::ikIsX  >() << endl;
   cout << getIsTrue< isX<char>::ikIsX  >() << endl;

resultar em 3 instanciações de modelos para três tipos: Int8, UINT8 e CHAR. O que da?

O mesmo não se aplica ao INTS: int e uint32 que resultam na mesma instanciação de modelo e assinou em outro.

O motivo parece ser que C ++ vê Char, Char assinado e char não assinado como três tipos diferentes. Enquanto int é o mesmo que um int. Isso está certo ou estou perdendo alguma coisa?

#include <iostream>

using namespace std;

typedef   signed char       int8;
typedef unsigned char      uint8;
typedef   signed short      int16;
typedef unsigned short     uint16;
typedef   signed int        int32;
typedef unsigned int       uint32;
typedef   signed long long  int64;
typedef unsigned long long uint64;

struct TrueType {};
struct FalseType {};

template <typename T>
struct isX
{
   typedef typename T::ikIsX ikIsX;
};


// This  int==int32 is ambiguous
//template <>            struct isX<int  >    { typedef FalseType ikIsX; };  // Fails
template <>            struct isX<int32  >  { typedef FalseType ikIsX; };
template <>            struct isX<uint32 >  { typedef FalseType ikIsX; };


// Whay isn't this ambiguous? char==int8
template <>            struct isX<char  >  { typedef FalseType ikIsX; };
template <>            struct isX<int8  >  { typedef FalseType ikIsX; };
template <>            struct isX<uint8 >  { typedef FalseType ikIsX; };


template <typename T> bool getIsTrue();
template <>           bool getIsTrue<TrueType>() { return true; }
template <>           bool getIsTrue<FalseType>() { return false; }

int main(int, char **t )
{
   cout << sizeof(int8) << endl;  // 1
   cout << sizeof(uint8) << endl; // 1
   cout << sizeof(char) << endl;  // 1

   cout << getIsTrue< isX<int8>::ikIsX  >() << endl;
   cout << getIsTrue< isX<uint8>::ikIsX  >() << endl;
   cout << getIsTrue< isX<char>::ikIsX  >() << endl;

   cout << getIsTrue< isX<int32>::ikIsX  >() << endl;
   cout << getIsTrue< isX<uint32>::ikIsX  >() << endl;
   cout << getIsTrue< isX<int>::ikIsX  >() << endl;

}

Estou usando g ++ 4. algo

Foi útil?

Solução

Aqui está a sua resposta do padrão:

3.9.1 Tipos fundamentais [Basic.Fundamental

Objetos declarados como caracteres (char) deve ser grande o suficiente para armazenar qualquer membro do conjunto de caracteres básicos da implementação. Se um caractere deste conjunto for armazenado em um objeto de caractere, o valor integral desse objeto de caractere será igual ao valor da forma literal de caractere única desse caractere. É definido pela implementação se um char Objeto pode conter valores negativos. Os personagens podem ser explicitamente declarados unsigned ou signed. Avião char, signed char, e unsigned char são três tipos distintos. UMA char, uma signed char, e um unsigned char ocupar a mesma quantidade de armazenamento e tem os mesmos requisitos de alinhamento (Basic.Types); isto é, eles têm a mesma representação de objetos. Para os tipos de caracteres, todos os bits da representação do objeto participam da representação do valor. Para tipos de caracteres não assinados, todos os padrões de bits possíveis da representação do valor representam números. Esses requisitos não se mantêm para outros tipos. Em qualquer implementação em particular, uma planície char o objeto pode assumir os mesmos valores que um signed char ou um unsigned char; qual é definido por implementação.

Outras dicas

Para perguntas como essa, gosto de examinar o documento de justificativa para C, que geralmente fornece respostas aos mistérios C ++, que às vezes surgem para mim ao ler o padrão. Tem isso a dizer sobre isso:

Três tipos de char são especificados: assinados, simples e não assinados. Um char simples pode ser representado como assinado ou não assinado, dependendo da implementação, como na prática anterior. O char assinado do tipo foi introduzido para disponibilizar um tipo inteiro assinado de um bytes nos sistemas que implementam o char simples como não assinado. Por razões de simetria, a palavra -chave assinada é permitida como parte do nome do tipo de outros tipos integrais.

Justificativa para c

Enquanto a maioria dos tipos integrais como short e int padrão para ser signed, char não possui uma sinalização padrão no C ++.

É um erro comum que os programadores C ++ encontram quando usam char como um tipo inteiro de 8 bits.

está correto, char, unsigned char e signed char são tipos separados. Provavelmente teria sido bom se char era apenas um sinônimo de qualquer signed char ou unsigned char Dependendo da implementação dos compiladores, mas o padrão diz que eles são tipos separados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top