Информация об изменениях

Сообщение Re: Обернуть С API от 04.04.2017 12:43

Изменено 04.04.2017 12:49 rg45

Re: Обернуть С API
Здравствуйте, Kernan, Вы писали:

K>Привет,

K>Есть C API работу с которым хочется обернуть т.к. для использования API надо выполнить некоторые рутинные вещи. Проблема в том, параметр в виде структуры передающиеся в функцию-обёртку могут иметь, а могут не иметь некоторых полей для заполнения, следовательно, нужно выбирать алгоритмы с разными рутинами. Я осилил создание шаблона HasField для проверки наличия поля в структуре честно сперев его на SO и не разобравщись как оно работает , но не понимаю как это использовать для выбора алгоритма.
K>...
K>Хочется увидеть код здорового человека. Нужен С++11, желательно чтобы был совместим с C++0x, т.е. поддержка не очень свежим gcc.

http://ideone.com/eCjdPX
template <typename T, typename = size_t>
struct HasField_abc : std::false_type { };
 
template <typename T>
struct HasField_abc<T, decltype(sizeof(std::declval<T>().abc))> : std::true_type { };
 
template <typename T>
std::enable_if_t<HasField_abc<T>::value> get(T&)
{
    std::cout << "Has abc" << std::endl;
    // . . .
}
 
template <typename T>
std::enable_if_t<!HasField_abc<T>::value> get(T&)
{
    std::cout << "Has no abc" << std::endl;
    // . . .
}
Re: Обернуть С API
Здравствуйте, Kernan, Вы писали:

K>Привет,

K>Есть C API работу с которым хочется обернуть т.к. для использования API надо выполнить некоторые рутинные вещи. Проблема в том, параметр в виде структуры передающиеся в функцию-обёртку могут иметь, а могут не иметь некоторых полей для заполнения, следовательно, нужно выбирать алгоритмы с разными рутинами. Я осилил создание шаблона HasField для проверки наличия поля в структуре честно сперев его на SO и не разобравщись как оно работает , но не понимаю как это использовать для выбора алгоритма.
K>...
K>Хочется увидеть код здорового человека. Нужен С++11, желательно чтобы был совместим с C++0x, т.е. поддержка не очень свежим gcc.

http://ideone.com/eCjdPX
template <typename T, typename = size_t>
struct HasField_abc : std::false_type { };
 
template <typename T>
struct HasField_abc<T, decltype(sizeof(std::declval<T>().abc))> : std::true_type { };
 
template <typename T>
std::enable_if_t<HasField_abc<T>::value> get(T&)
{
    std::cout << "Has abc" << std::endl;
    // . . .
}
 
template <typename T>
std::enable_if_t<!HasField_abc<T>::value> get(T&)
{
    std::cout << "Has no abc" << std::endl;
    // . . .
}


Для не очень свежего gcc, возможно, придется использовать std::enable_if вместо std::enable_if_t, ну или определить собственный аналог для компактности кода.