Как установить член, только если он существует? - PullRequest
4 голосов
/ 15 сентября 2011

Редактировать: Извините, этот вопрос является дубликатом.Оригинал: SFINAE для проверки унаследованных функций-членов

У меня есть шаблонная функция (в классе, используемом для тестирования):

template <class CHandler>
void InitHandler(CHandler &handler)
{
    handler.setId(0);
    handler.SetCache(m_pCache.get());
    handler.m_pScience = m_pScience;
}

Однако возможно, что этоФункция может вызываться с аргументом шаблона, который не имеет члена m_pScience.

Могу ли я использовать метапрограммирование шаблона, чтобы установить этот элемент, только если он существует?

Ответы [ 2 ]

5 голосов
/ 15 сентября 2011

Переосмысление этого ответа: Как определить, есть ли конкретная переменная-член в классе? :

template<typename T> struct Hasm_pScience 
{ 
    struct Fallback { int m_pScience; }; // introduce member name "m_pScience"
    struct Derived : T, Fallback { };

    template<typename C, C> struct ChT; 

    template<typename C> static char (&f(ChT<int Fallback::*, &C::m_pScience>*))[1]; 
    template<typename C> static char (&f(...))[2]; 

    static bool const value = sizeof(f<Derived>(0)) == 2;
}; 

struct A { float m_pScience; };
struct B { int X; };

int main(int argc, _TCHAR* argv[])
{
    std::cout << Hasm_pScience<A>::value << std::endl; // 1
    std::cout << Hasm_pScience<B>::value << std::endl; // 0

    return 0;
}

Общий принцип, по которому Google обращается к SFINAE (ошибка замещения не являетсяошибка).

1 голос
/ 15 сентября 2011

Обычно, когда вам нужен определенный элемент в шаблоне, вы должны заставить пользователей шаблона применять его, даже если он для них не имеет смысла.Типичными примерами являются stl set и map, где вам нужно определить operator <.

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

У вас также может быть два шаблона: один для тех, у кого есть m_pScience, и другой для тех, у кого его нет, но я не рекомендую этого.Таким образом, вы всегда должны быть уверены, что код между двумя шаблонами согласован.

...