Pergunta

Considere uma classe de modelo como:

template<typename ReturnType, ReturnType Fn()>
class Proxy
{
    void run()
    {
        ReturnType ret = Fn();
        // ... do something ...
    }
};

// and a functions
int fn1() { return 5; }
float fn2() { return 5; }

Isto pode ser instanciado usando:

Proxy<int, &fn1> p1;

Mas explicitamente declarar o tipo de valor de retorno parece desnecessária. O que estou tentando alcançar é algo como:

 someProxyInstantation<&fn1> p1;
 someProxyInstantation<&fn2> p2;

Infelizmente, não sou C ++ esperar e este parece ser um canto escondido da língua (pelo menos para mim).

Se eu pudesse começar a partir do ponteiro para a função para seu tipo - algo como: std :: tr1 :: result_of <& fn> :: tipo // erro 1 Erro C2923: 'std :: tr1 :: result_of': 'fn1' não é um argumento de tipo de modelo válido para o parâmetro '_Fty'

o erro faz sentido uma vez que o parâmetro não é um "tipo" de todo

C ++ 0x tem a decltype (& FN1), mas que está a anos de distância.

Qualquer maneira de fazer isso em C ++ 03 (+ tr1)?

Restrições: - Eu não quero passar o functor, F1 e F2 tem que permanecer funções globais que têm um valor de retorno (não pode movê-lo para parâmetros))

.
Foi útil?

Solução

Isto não é possível em C ++ 03. Se você quiser passar um ponteiro função como um parâmetro não-tipo, o compilador tem que saber o tipo de parâmetro. Então você tem que fornecer as peças que faltam (neste caso, o tipo de retorno). Você pode dar o proxy o ponteiro de função como um valor em tempo de execução, e fornecê-lo com o tipo dele como o único argumento. Em seguida, você pode escrever uma função de gerador para você que faz este trabalho:

template<typename T>
Proxy<T> make_proxy(T t) { return Proxy<T>(t); }

Infelizmente, na atual C ++, você ainda tem que dar-lhe o tipo, a fim de atribuir a uma variável automática:

Proxy<int(*)()> p = make_proxy(&fn1);

Você não pode usar auto p = make_proxy(&fn1); ainda. Note que se você quiser usar um tipo de função no lado esquerdo, você tem que mudar a função de gerador para fornecer não um tipo de ponteiro de função:

template<typename T>
Proxy<typename boost::remove_pointer<T>::type> make_proxy(T t) { 
    return Proxy<typename boost::remove_pointer<T>::type>(t); 
}

Agora você pode fazer

Proxy<int()> p = make_proxy(&fn1);

usando o proxy, agora você pode apenas fazer

doSomething(make_proxy(&fn1));

E se doSomething é templated ou não polimórficos, não vai exigir que você sabe o tipo exato da função.

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