classe de modelo dentro de modelo de classe em C ++
-
11-09-2019 - |
Pergunta
Noob aqui ainda experimentar com modelos. Tentando escrever um modelo de classe de processamento de mensagens
template <typename T> class MessageProcessor {
//constructor, destructor defined
//Code using t_ and other functions
foo( void ) {
//More code in a perfectly fine method
}
private: T *t_
};
Tudo definido em um arquivo de cabeçalho. Eu já construído e testado a minha classe e está tudo bem. Agora, eu estou tentando fazer isso:
template <typename T> class MessageProcesor {
//Same stuff as before
foo(void) {
//Same code as before in foo, but one new line:
t_->getMessageSender<MessageType>();
}
private: T *t_;
};
No entanto, esta linha me dá um erro de expressão ruim do tipo antes de '>' token.
Eu adicionei os arquivos de cabeçalho necessários para definir o que é um MessageType é. Eu usei esta função muitos tempo antes, não apenas neste contexto.
Eu suspeito que o compilador não gosta do fato de que a função de modelo está totalmente definido (especializado?) Dentro de um modelo de classe indefinido (não especializadas?). Eu não estou totalmente grokking o que faz um modelo 'especializada'. Mais explicações centro sobre os conceitos de 'cheio' ou 'parcial', mas não o que faz com que seja especializada em primeiro lugar.
Desculpas se você gostaria de ver mais código. Eu não tenho acesso à Internet no trabalho e que é onde eu estou fazendo isso, então eu tenho que colocar tudo em meu 'rascunho' mental e trazê-lo para casa.
Solução
A sua função de membro 'foo' precisa de um tipo de retorno e você precisa usar a palavra-chave 'modelo' quando você usa modelos de membros em expressões dependentes (expressões cujos significados dependem direta ou indiretamente em um parâmetro do modelo genérico)
t_->template getMessageSender<MessageType>(); // ok
t_->getMessageSender<MessageType>(); // not ok
Talvez este exemplo irá ajudá-lo a apreciar quando um modelo membro do precisa para ser prefixados pelo 'modelo' palavra-chave [Nota: no interesse de simetria que você pode usar sempre o 'modelo' de prefixo em membro modelos, mas é opcional quando usado em uma expressão não-dependentes.
struct MyType
{
template<class T> void foo() { }
};
template<class U>
struct S
{
template<class T>
void bar()
{
MyType mt; // non-dependent on any template parameter
mt.template foo<int>(); // ok
mt.foo<int>(); // also ok
// 't' is dependent on template parameter T
T t;
t.template foo<int>(); // ok
t.foo<int>(); // not ok
S<T> st; // 'st' is dependent on template parameter T
st.template foo<int>(); // ok
st.foo<int>(); // not ok
S<MyType> s; // non-dependent on any template parameter
s.bar<int>(); // ok
s.template bar<int>(); // also ok
}
};
Espero que ajude.
Outras dicas
Adicionar a palavra-chave template
entre ->
e o nome do método de modelo:
t_->template getMessageSender<MessageType>();
Provavelmente, MessageType não é conhecido nesse ponto. Você está faltando um incluem, uma resolução namespace ou uma declaração?
Se tht não é isso, como é getMessageSender
declarou, e como é MessageType
?
Geralmente, em C ++ não é um problema se T não se sabe em que ponto (bem ... é complicado, mas ainda).
Além disso, a mensagem de erro normalmente contém o tipo para o qual tenta-se ser insantiated. Tente postar a mensagem de erro completa, pelo menos.
Você tem outras chamadas semelhantes aos métodos como getMessageSender que são templatized?
t_->getMessageSender<MessageType>();
É apenas o tipo de retorno de sua função que está faltando. O membro t_
está totalmente definido.
A especialização de um modelo é uma versão 'especial' a sua implementação para argumentos de modelo específicos. Um exemplo:. std::vector
é a versão especializada do std::vector
genérico
A especialização parcial é uma implementação do seu código genérico em que nem todos os argumentos de modelo são fornecidos.
Esta multa trabalha no compilador Visual Studio 2010.
class One
{
public:
void newFoo() ;
template < class T > void foo()
{
T obj ; // obj is dependent on template parameter
obj.newFoo() ; // and this works
}
}
Apenas para manter a resposta atualizada !!!