Вывести аргумент шаблона функции для базового класса - PullRequest
0 голосов
/ 20 сентября 2018

В этом примере мне нужно только создать экземпляр функции шаблона для типов базовых классов.

struct A{ int i=0; };
struct A1:A{};
struct A2:A{};

struct B{ int i=1; };
struct B1:B{};
struct B2:B{};

template<typename T> uint32_t Checksum ( const T& t )
{
    // make sure we are not instantiating redundant functions
    static_assert(std::is_same<T,A>::value || std::is_same<T,B>::value,"");

    return t.i;
}
template uint32_t Checksum ( const A& t ); //this are actually no ops
template uint32_t Checksum ( const B& t ); //this are actually no ops

int main()
{
    A1 a1;
    A2 a2;
    B1 b1;
    B2 b2;
    Checksum<A>(a1);//ok
    Checksum<A>(a2);//ok
    Checksum<B>(b1);//ok
    Checksum<B>(b2);//ok
    Checksum(b2);  //error

    return 0;
}

Можно ли принудительно вывести тип шаблона в базовый класс, в идеале без руководств по выводу C ++ 17, так что мне не нужно указывать тип при вызове?

Я также пытался явным образом создать экземпляр функции, задаваясь вопросом, будут ли они в конечном итоге воспроизводиться с разрешением перегрузки функции, но компилятор не выбирает их.Возможно, с этим возможен какой-то трюк.

1 Ответ

0 голосов
/ 20 сентября 2018

Как насчет:

foo.h

struct A{ int i=0; };
struct A1:A{};
struct A2:A{};

struct B{ int i=1; };
struct B1:B{};
struct B2:B{};

uint32_t Checksum ( const A& t );
uint32_t Checksum ( const B& t );

checkSum.cpp

#include "foo.h"

template<typename T> uint32_t ChecksumImpl ( const T& t )
{
    // make sure we are not instantiating redundant functions
    static_assert(std::is_same<T,A>::value || std::is_same<T,B>::value,"");

    return t.i;
}
uint32_t Checksum ( const A& t ) { return ChecksumImpl (t);}
uint32_t Checksum ( const B& t ) { return ChecksumImpl (t);}

main.cpp

#include "foo.h"

int main()
{
    A1 a1;
    A2 a2;
    B1 b1;
    B2 b2;
    Checksum(a1);//ok
    Checksum(a2);//ok
    Checksum(b1);//ok
    Checksum(b2);//ok
}
...