Определите, имеет ли тип конкретную сигнатуру функции-члена - PullRequest
2 голосов
/ 21 апреля 2011
template<typename U> struct CheckSignature {
    enum {SizeTrue = 1, SizeFalse = 2};
    typedef char ReturnTrue[SizeTrue];
    typedef char ReturnFalse[SizeFalse];
    typedef typename U::iterator (U::*InsertSig)(typename U::iterator, typename const U::value_type &);
    static ReturnTrue &CheckInsert(InsertSig);
    static ReturnFalse &CheckInsert(...);
    static const bool value = (sizeof(CheckInsert(&U::insert)) == sizeof(ReturnTrue));
};

int main() {
    CheckSignature<std::string >::value; //compile error
    CheckSignature<std::vector<int> >::value; // OK
    return 0;
}

Этот код генерирует ошибку компиляции для строкового класса, говоря, что ни одна из двух перегрузок не может преобразовать все типы аргументов.Однако для вектора это компилируется нормально.Не следует ли перегрузить разрешение, выбирая CheckInsert (...), если параметр не относится к типу InsertSig?

Ответы [ 2 ]

2 голосов
/ 21 апреля 2011

Попробуйте вместо этого:

#include <string>
#include <vector>
#include <iostream>

template<typename U> struct CheckSignature {
    enum {SizeTrue = 1, SizeFalse = 2};
    typedef char ReturnTrue[SizeTrue];
    typedef char ReturnFalse[SizeFalse];
    typedef typename U::iterator (U::*InsertSig)(typename U::iterator, typename U::value_type const &);
    template <InsertSig f> struct dummy_type { };
    template <typename T>
    static ReturnTrue &CheckInsert(T*, dummy_type<&T::insert> dummy = dummy_type<&T::insert>());
    static ReturnFalse &CheckInsert(...);
    static const bool value = (sizeof(CheckInsert(((U*)0))) == sizeof(ReturnTrue));
};

int main() {
    if(CheckSignature<std::string >::value) {
      std::cout << "String class has proper insert function" << std::endl;
    }; //OK, does not print, as expected.
    if(CheckSignature<std::vector<int> >::value) {
      std::cout << "Vector class has proper insert function" << std::endl;
    }; //OK, does print, as expected.
    return 0;
}

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

0 голосов
/ 21 апреля 2011

std::string::insert не принимает параметр const char&, а только char.

Кроме того, в зависимости от того, как далеко продвинулась реализация в поддержке C ++ 11,Контейнеры могут использовать const_iterator (вместо итератора) для указания позиции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...