Pergunta

Em C # podemos definir um tipo genérico que impõe restrições sobre os tipos que podem ser usados ??como parâmetro genérico. O exemplo a seguir ilustra o uso de restrições genéricas:

interface IFoo
{
}


class Foo<T> where T : IFoo
{
}

class Bar : IFoo
{
}

class Simpson
{
}

class Program
{
    static void Main(string[] args)
    {
        Foo<Bar> a = new Foo<Bar>();
        Foo<Simpson> b = new Foo<Simpson>(); // error CS0309
    }
}

Existe uma maneira podemos impor restrições para parâmetros do modelo em C ++.


C ++ 0x tem suporte nativo para isso, mas eu estou falando sobre a atual padrão C ++.

Foi útil?

Solução

Como alguém mencionou, C ++ 0x está recebendo este construído dentro da linguagem. Até então, eu recomendo Bjarne Stroustrup 's impulsionar também tem um alternativa de sua própria .

Edit2: Parece conceitos foram removidos do C ++ 0x .

Outras dicas

Se você usar C ++ 11, você pode usar static_assert com std::is_base_of para esta finalidade.

Por exemplo,

#include <type_traits>

template<typename T>
class YourClass {

    YourClass() {
        // Compile-time check
        static_assert(std::is_base_of<BaseClass, T>::value, "type parameter of this class must derive from BaseClass");

        // ...
    }
}

"Implicitamente" é a resposta correta. Modelos efetivamente criar um cenário de "pato digitação", devido à forma como eles são compilados. Você pode chamar quaisquer funções que você deseja em cima de um valor digitado-modelo, e as únicas instâncias que serão aceitos são aqueles em que esse método é definido. Por exemplo:

template <class T>
int compute_length(T *value)
{
    return value->length();
}

Podemos chamar esse método em um ponteiro para qualquer tipo que declara o método length() para retornar um int. Assim:

string s = "test";
vector<int> vec;
int i = 0;

compute_length(&s);
compute_length(&vec);

... mas não em um ponteiro para um tipo que faz não declarar length():

compute_length(&i);

Este terceiro exemplo não será compilado.

Isso funciona porque C ++ compila uma nova versão da função templatized (ou classe) para cada instanciação. Como ele executa que a compilação, ele faz uma direta, quase macro-como substituição da instanciação de modelo no código antes da verificação de tipo. Se tudo ainda funciona com esse modelo, compilação prossegue então e que, eventualmente, chegar a um resultado. Se alguma coisa falhar (como int* length() não declarar), então nós começamos a seis páginas de erro modelo de tempo de compilação temido.

Você pode colocar um tipo de guarda em IFoo que não faz nada, certifique-se de que ele está lá em T em Foo:

class IFoo
{
public:
    typedef int IsDerivedFromIFoo;
};

template <typename T>
class Foo<T>
{
    typedef typename T::IsDerivedFromIFoo IFooGuard;
}

Confira impulso

O impulso Conceito Verifique Library (BCCL)

O Check biblioteca Concept permite adicionar declaração explícita e verificação de conceitos no estilo do proposta C ++ linguagem de extensão .

Mais ou menos. Se você static_cast a um IFoo *, então será impossível para instanciar o modelo a menos que o chamador passa uma classe que pode ser atribuído a um IFoo *.

Apenas implicitamente.
Qualquer método que você usa em um método que é realmente chamado é imposta ao parâmetro do modelo.

Você pode fazê-lo. Crie o modelo base. Torná-lo ter construtores única privados. Em seguida, criar especializações para cada caso você deseja permitir (ou fazer o oposto, se a lista não permitido é muito menor do que a lista de permitidos).

O compilador não permitirá que você para instanciar os modelos que usam a versão com construtores privados.

Este exemplo só permitir instanciação com int e float.

template<class t> class FOO { private: FOO(){}};

template<> class FOO<int>{public: FOO(){}};

template<> class FOO<float>{public: FOO(){}};

A sua não é uma forma curta e elegante de fazê-lo, mas a sua possível.

Observe o modelo CRTP (Pattern Template recursiva Curiosamente). Ele é projetado para inheritence apoio ajuda estático.

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