Pergunta

O que é a diferença entre

(type)value

e

type(value)

em C ++?

Foi útil?

Solução

Não há nenhuma diferença; pelo padrão (§5.2.3):

Um tipo simples especificador (7.1.5), seguido de uma expressão de parêntesis lista constrói um valor do tipo especificado, dada a lista de expressão. Se a lista de expressão é uma única expressão, a expressão conversão tipo é equivalente (em definedness, e se definido em sentido) para a expressão de conversão correspondente (5,4).

Uma vez que a questão especificado a diferença entre type(value) e (type)value, não há absolutamente nenhuma diferença.

Se e somente se você está lidando com um lista separada por vírgulas de valores pode haver uma diferença. Neste caso:

Se a lista de expressão especifica mais do que um único valor, o tipo deve ser uma classe com um construtor adequadamente declarado (8.5, 12.1), ea expressão T (x1, x2, ...) é equivalente em efeito à declaração T t (x1, x2, ...); para alguns inventado variável t temporária, com o resultado sendo o valor de t como um rvalue.

Como Troubadour apontou, há certos nomes de tipos para o qual a versão type(value) simplesmente não vai compilar. Por exemplo:

char *a = (char *)string;

irá compilar, mas:

char *a = char *(string);

não. O mesmo tipo com um nome diferente (por exemplo, criado com um typedef) pode trabalhar no entanto:

typedef char *char_ptr;

char *a = char_ptr(string);

Outras dicas

Não há nenhuma diferença; o padrão C ++ (1998 e 2003 edições) é clara sobre este ponto. Tente o seguinte programa, certifique-se de usar um compilador que é compatível, como a visualização gratuita em http://comeaucomputing.com/ tryitout / .

#include <cstdlib>
#include <string>
int main() {
  int('A'); (int) 'A'; // obvious
  (std::string) "abc"; // not so obvious
  unsigned(a_var) = 3; // see note below
  (long const&) a_var; // const or refs, which T(v) can't do
  return EXIT_SUCCESS;
}

Nota: unsigned(a_var) é diferente, mas não mostrar uma maneira esses símbolos exatos pode significar outra coisa. É declarar uma variável chamada a_var de tipo não assinado, e não é um elenco em tudo. (Se você estiver familiarizado com ponteiros para funções ou matrizes, considere como você tem que usar um parênteses em torno p em um tipo como void (*pf)() ou int (*pa)[42].)

(Os avisos são produzidos uma vez que estas declarações não use o valor e em um programa real que tinha quase certamente ser um erro, mas tudo ainda funciona. Eu só não tenho o coração para mudá-lo depois de fazer tudo linha -se.)

Não há diferença quando ambos são elencos, mas às vezes 'tipo (valor)' não é um elenco.

Aqui está um exemplo de projecto de norma N3242, seção 8.2.1:

struct S 
{
    S(int);
};

void foo(double a) 
{
    S w( int(a) ); // function declaration
    S y( (int)a ); // object declaration
}

Neste caso 'int (a)' não é um elenco, porque 'a' não é um valor, é um nome de parâmetro entre parênteses redundantes. O documento afirma

A ambiguidade decorrente da semelhança entre um estilo de função elenco e uma declaração mencionada em 6.8 também pode ocorrer no contexto de uma declaração. Nesse contexto, a escolha é entre uma função declaração com um conjunto redundante de parênteses em torno de um parâmetro nome e uma declaração de objeto com um elenco de estilo função que a initializer. Assim como para as ambiguidades mencionados em 6.8, o resolução é a de considerar qualquer construção que poderia ser um declaração de uma declaração.

Em c não há type (value), enquanto em c / c ++ tanto type (value) e (type) value são permitidos.

Para ilustrar suas opções em C ++ (apenas um tem uma verificação de segurança)

#include<boost/numeric/conversion/cast.hpp> 

using std::cout;
using std::endl;
int main(){

    float smallf = 100.1;

    cout << (int)smallf << endl; // outputs 100 // c cast
    cout << int(smallf) << endl; // outputs 100 // c++ constructor = c cast

    cout << static_cast<int>(smallf) << endl; // outputs 100
//  cout << static_cast<int&>(smallf) << endl; // not allowed
    cout << reinterpret_cast<int&>(smallf) << endl; // outputs 1120416563
    cout << boost::numeric_cast<int>(smallf) << endl; // outputs 100

    float bigf = 1.23e12;

    cout << (int)bigf << endl; // outputs -2147483648
    cout << int(bigf) << endl; // outputs -2147483648

    cout << static_cast<int>(bigf) << endl; // outputs -2147483648
//  cout << static_cast<int&>(bigf) << endl; // not allowed
    cout << reinterpret_cast<int&>(bigf) << endl; // outputs 1401893083
    cout << boost::numeric_cast<int>(bigf) << endl; // throws bad numeric conversion
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top