2016-11-15 15 views
8

Mam zestaw funkcji, które działają na klasach szablonowych, ale nie polegają na szablonach części klasy.Funkcja C++ dla struct bez względu na typy szablonów

Templowanie funkcji i pozwalanie jej na dedukcję typów będzie działało, ale zostanie skompilowane do wielu funkcji.

#include <iostream> 

template<typename T> 
struct MyStruct { 
    int a; 
    T b; 
}; 


bool isLess(MyStruct& lhs, MyStruct& rhs) { 
    return lhs.a < rhs.a; 
} 


int main(int argc, char const *argv[]) 
{ 
    MyStruct<int> x {123, 456}; 
    MyStruct<int> y {789, 123}; 

    std::cout << isLess(x, y) << std::endl; 

    return 0; 
} 

Czy istnieje sposób, aby to osiągnąć?

+0

Jeśli zdefiniujesz funkcję składową w deklaracji klasy, nie musisz uwzględniać żadnych parametrów szablonu, jeśli nie ulegną one zmianie. –

Odpowiedz

12

Dokonaj refaktoryzacji pól, które nie zależą od T w innej klasie. Dokonaj MyStruct<T> Dziedziczy z niego:

struct MyStructBase 
{ 
    int a; 
}; 

template<typename T> 
struct MyStruct : MyStructBase 
{ 
    T b; 
}; 

bool isLess(MyStructBase& lhs, MyStructBase& rhs) { 
    return lhs.a < rhs.a; 
} 

int main(int argc, char const *argv[]) 
{ 
    MyStruct<int> x {123, 456}; 
    MyStruct<int> y {789, 123}; 

    std::cout << isLess(x, y) << std::endl; 

    return 0; 
} 
9

Można użyć dziedziczenia:

struct MyStructBase { 
    int a; 
}; 

template<typename T> 
struct MyStruct : public MyStructBase { 
    T b; 
}; 


bool isLess(MyStructBase& lhs, MyStructBase& rhs) { 
    return lhs.a < rhs.a; 
} 
1

miałbym to zrobić:

template<typename L, typename R> 
auto isLess(L&& lhs, R&& rhs) -> decltype(std::declval<L>().a < std::declval<R>().a) { 
    return std::forward<L>(lhs).a < std::forward<R>(rhs).a; 
} 

to będzie działać niezależnie od relacji pomiędzy swoim rodzaju i będzie nie kompiluje się do wielu funkcji (patrz ostatni akapit). Pozwoli to wszystkim typom, które mają członka, który jest mniej niż porównywalny.

Templowanie funkcji i pozwalanie jej na dedukcję typów będzie działać, ale będzie następnie kompilowane do wielu funkcji.

Złe domysły. To nawet lepsze, kompiluje się do żadnej funkcji w ogóle, ponieważ każdy rozsądny kompilator (nawet msvc) całkowicie zainicjuje funkcję.

+0

Bardzo schludne i krótkie rozwiązanie! PO powinien to zaakceptować. _ "nawet msvc" _ LOL: D –

+0

Twoja instrukcja return jest nieprawidłowa (R zamiast L dla lhs). – overseas

+0

Ups, przepraszam, pozwól mi to naprawić. –

Powiązane problemy