UPD 03.12.2016: можно сделать это гораздо проще: //... template<typename T> bool execute_work(T &t) { static_assert(std::is_base_of<A, T>::value, "T must be subclass of A"); t.do_work(); } int main() { B b; C c; execute_work(b); //OK execute_work(c); //compile error } И теперь у нас компилятор будет выдавать именно то сообщение, которое мы указали в static_assert |
четверг, 17 ноября 2016 г.
Использование is_base_of и enable_if и детектирование типов во время компиляции
Допустим у нас есть некая функция, которая должна быть определена только для наследников определенного класса. Можно сделать это в рантайме, но детектирование типов в рантайме это дорого и к тому же некрасиво. C++11 предлагает более красивое решение.
Ярлыки:
C++,
C++11,
enable_if,
is_base_of,
static_assert,
STL,
template
четверг, 10 ноября 2016 г.
Передача определений прекомпиляции из cmake
Довольно частая задача, чтобы например подключать те или иные заголовки и делать это можно конечно только во время прекомпиляции.
Допустим есть такой CMakeLists.txt файл:
set(MYTARGET "target")
# we have some string var that we want to convert to correct define for pre-compiler
set(INTERFACES_VERSION_STR "-2016.10.23-" )
# remove all points (".")
string(REPLACE "." "" MY_INTERFACES_VER ${INTERFACES_VERSION_STR})
# remove all "-" symbols
string(REPLACE "-" "" MY_INTERFACES_VER ${MY_INTERFACES_VER})
# print them
message(STATUS "INTERFACES_VERSION_STR ${INTERFACES_VERSION_STR}")
message(STATUS "MY_INTERFACES_VER ${MY_INTERFACES_VER}")
add_library(${MYTARGET} my_source.cpp)
add_definitions(-DMY_INTERFACES_VER=${MY_INTERFACES_VER})
Допустим есть такой CMakeLists.txt файл:
set(MYTARGET "target")
# we have some string var that we want to convert to correct define for pre-compiler
set(INTERFACES_VERSION_STR "-2016.10.23-" )
# remove all points (".")
string(REPLACE "." "" MY_INTERFACES_VER ${INTERFACES_VERSION_STR})
# remove all "-" symbols
string(REPLACE "-" "" MY_INTERFACES_VER ${MY_INTERFACES_VER})
# print them
message(STATUS "INTERFACES_VERSION_STR ${INTERFACES_VERSION_STR}")
message(STATUS "MY_INTERFACES_VER ${MY_INTERFACES_VER}")
add_library(${MYTARGET} my_source.cpp)
add_definitions(-DMY_INTERFACES_VER=${MY_INTERFACES_VER})
Тогда в исходном файле пишем:
//...
#if MY_INTERFACES_VER==20161023
#include "v20161023/include/interfaces.h"
#include "v20161023/include/interfaces.h"
std::cout << "---- MY_INTERFACES_VER==20161023 ---" << std::endl;
#else
#include "mainline/include/interfaces.h"
#include "mainline/include/interfaces.h"
std::cout << "do some by default " << std::endl;
#endif
Подписаться на:
Сообщения (Atom)