C++ return null

Oi pessoal

Meu maior problema é que tento fazer as coisas em C++ da forma com que eu fazia em Java, e isso nem sempre é uma boa escolha.

Para treinar, estou criando uma lista encadeada em C++ (usando templates). Em um dado momento, fui criar o método remover, veja abaixo:

No início do código coloquei

#define null 0

Mais lá pro final, cheguei a esse impasse:

int getIndice(T alvo)
 {
       Elemento *atual;
       atual = primeiro;
       int i = 0;
       while (atual != null)
       {
              if (atual->elem == alvo)
              {
                     return i;
               }
               i++;
              atual = atual->proximo;
       }
       return -1;
}
T remover(T elemento)
{
       int indice = getIndice(elemento);
       if (indice == -1)
       {
              return null; // erro aqui. Não necessariamente isso é um ponteiro
       }
       return remover(indice);
 }
T remover(int indice)
{
       if (ehVazia())
       {

       }
 }

O problema é que em Java tudo é pointeiro, então no método removerInicio(T elemento), caso o índice do elemento fosse -1 (não existe), ele deveria retornar null. Isso em C++ não funciona, pois não necessariamente essa lista encadeada será de ponteiros.

Esse problema (ter uma lista encadeada tanto de ponteiros quanto de não-ponteiros) me deixou sem solução. Será que alguém teria alguma ideia para me ajudar a resolver esse impasse? Tipo o que retornar ou que modificações eu deveria fazer? Eu não gostaria de obrigar que minha lista só aceitasse ponteiros.

Muito obrigado.

O C++ já define por padrão o valor NULL, como zero. Não é necessário fazer um null minúsculo com define.
Aliás, define é uma péssima forma de criar constantes, o ideal mesmo seria usar static const.

No caso do C++11 (se vc estiver usando uma versão nova do visual ou o MSVC2010), use nullptr, que é typesafe.

Quanto a sua lista.
Não vejo muitas formas de você resolver isso, já que você NUNCA terá um valor padrão para retornar, caso tipo não seja um ponteiro.
Nesse caso, como você gostaria que a lista se comportasse? Você terá que repensar na assinatura de seus métodos.

Até é possível contornar o problema usando Template Specialization, mas comumente, os métodos não mudam de assinatura quando criamos especializações (é possível, mas não é usual).

Oi Vini

Pois é, eu tive 4 cadeiras de C na faculdade (C, não C++) e o que mais me deixa confuso é o que eu "posso usar" em C++ proveniente do C (por exemplo, em C usa-se muito print, embora esteja disponível para se usar em C++, o pessoal acaba usando mais cout). O NULL era uma dessas minhas dúvidas, se podia ou não ser usado.

Obrigado, isso eu também não sabia.

Eu estou usando Code::Blocks no Ubuntu, vou pesquisar para descobrir se há algo a respeito.

Sim, é verdade. Uma coisa que lembro que eu fazia nas cadeiras da faculdade, em C, era criar um enum como condições de retorno possíveis para a função, algo assim:

OBS: Criei esse código agora e às pressas, ele não funciona, só para ilustrar como fazíamos as condições de retorno.

[code]
typedef enum ListaCondRet
{
OK,
ListaNaoInformada,
IndiceInvalido
} ListaCondRet;

ListaCondRet remover_elemento (Lista * lista, int indice, T * elemento)
{
int i = 0;
if (lista == NULL)
{
return ListaNaoInformada;
}

if (indice < 0 || indice > lista->getTamanho())
{
    return IndiceInvalido;
}

ElementoDaLista * atual = lista->primeiro;
while (i++ < indice)
{
    atual = atual->proximo;
}

elemento = atual->getValor();

// aqui desencadeia a lista

return OK;

}[/code]

[quote=ViniGodoy]
Até é possível contornar o problema usando Template Specialization, mas comumente, os métodos não mudam de assinatura quando criamos especializações (é possível, mas não é usual).[/quote]
Muito legal, vou dar uma lida.
Você acha ruim a ideia de utilizar as condições de retorno em C++?

Obrigado =D

Não acho não.
Uma alternativa em C++ seria usar exceptions.
Mas você não deve usa-las a menos que entenda o conceito de RAII, que é um tópico um pouco mais avançado.

Como exceptions em C++ tem um custo computacional relativamente alto, é bem comum vc ver por aí o pessoal tratar com valores de retorno mesmo.

Oi Vini

Obrigado, vou fazer dessa forma, então.