История изменений
Исправление PRN, (текущая версия) :
А как ты список тегов в темплейт передашь?
Списком типов. На C++17 приблизительно так:
#include <type_traits>
#include <tuple>
#include <iostream>
template <typename T, typename Tuple>
struct has_type: std::false_type {};
template <typename T, typename... Us>
struct has_type<T, std::tuple<Us...>> : std::disjunction<std::is_same<T, Us>...> {};
template <typename T, typename... Us>
inline constexpr bool has_type_v = has_type<T, Us...>::value;
struct foo_tag{};
struct bar_tag{};
struct AllGroup
{
using List = std::tuple<foo_tag, bar_tag>;
};
struct FooGroup
{
using List = std::tuple<foo_tag>;
};
template<class Group>
class log
{
public:
template<typename T = foo_tag>
std::enable_if_t<std::is_same_v<T, foo_tag> && has_type_v<foo_tag, typename Group::List>>
foo() { std::cout << "do foo\n"; }
template<typename T = foo_tag>
std::enable_if_t<std::is_same_v<T, foo_tag> && !has_type_v<foo_tag, typename Group::List>>
foo() { std::cout << "do nothing instead foo\n"; }
template<typename T = bar_tag>
std::enable_if_t<std::is_same_v<T, bar_tag> && has_type_v<bar_tag, typename Group::List>>
bar() { std::cout << "do bar\n"; }
template<typename T = bar_tag>
std::enable_if_t<std::is_same_v<T, bar_tag> && !has_type_v<bar_tag, typename Group::List>>
bar() { std::cout << "do nothing instead bar\n"; }
};
int main()
{
log<FooGroup> foo;
foo.foo();
foo.bar();
log<AllGroup> all;
all.foo();
all.bar();
}
Выведет:
do foo
do nothing instead bar
do foo
do bar
Про C++11 я забыл как про страшный сон))). По крайней мере большую часть того что выше написано на C++17, в C++11 можно заменить с помощью boost::mpl
, boost::tuple
и т.д.
Идея в том, чтобы можно было задать фильтры, и вызовы логера с ненужными тегами превратились в пустые функции
Еще условия в enable_if_t
поменять на противоположные)
Статик в теге пробовал. Та же фигня с линкером.
Юзай наследование:
class LogFooGroup : public log<FooGroup> ...
Оно должно помочь. Дальше везде LogFooGroup
вместо шаблона.
Исправление PRN, :
А как ты список тегов в темплейт передашь?
Списком типов. На C++17 приблизительно так:
#include <type_traits>
#include <tuple>
#include <iostream>
template <typename T, typename Tuple>
struct has_type: std::false_type {};
template <typename T, typename... Us>
struct has_type<T, std::tuple<Us...>> : std::disjunction<std::is_same<T, Us>...> {};
template <typename T, typename... Us>
inline constexpr bool has_type_v = has_type<T, Us...>::value;
struct foo_tag{};
struct bar_tag{};
struct AllGroup
{
using List = std::tuple<foo_tag, bar_tag>;
};
struct FooGroup
{
using List = std::tuple<foo_tag>;
};
template<class Group>
class log
{
public:
template<typename T = foo_tag>
std::enable_if_t<std::is_same_v<T, foo_tag> && has_type_v<foo_tag, typename Group::List>>
foo() { std::cout << "do foo\n"; }
template<typename T = foo_tag>
std::enable_if_t<std::is_same_v<T, foo_tag> && !has_type_v<foo_tag, typename Group::List>>
foo() { std::cout << "do nothing instead foo\n"; }
template<typename T = bar_tag>
std::enable_if_t<std::is_same_v<T, bar_tag> && has_type_v<bar_tag, typename Group::List>>
bar() { std::cout << "do bar\n"; }
template<typename T = bar_tag>
std::enable_if_t<std::is_same_v<T, bar_tag> && !has_type_v<bar_tag, typename Group::List>>
bar() { std::cout << "do nothing instead bar\n"; }
};
int main()
{
log<FooGroup> foo;
foo.foo();
foo.bar();
log<AllGroup> all;
all.foo();
all.bar();
}
Выведет:
do foo
do nothing instead bar
do foo
do bar
Про C++11 я забыл как про страшный сон))). По крайней мере большую часть того что выше написано, в C++11 можно заменить с помощью boost::mpl
Идея в том, чтобы можно было задать фильтры, и вызовы логера с ненужными тегами превратились в пустые функции
Еще условия в enable_if_t
поменять на противоположные)
Статик в теге пробовал. Та же фигня с линкером.
Юзай наследование:
class LogFooGroup : public log<FooGroup> ...
Оно должно помочь. Дальше везде LogFooGroup
вместо шаблона.
Исходная версия PRN, :
А как ты список тегов в темплейт передашь?
Списком типов. На C++17 приблизительно так:
#include <type_traits>
#include <tuple>
#include <iostream>
template <typename T, typename Tuple>
struct has_type: std::false_type {};
template <typename T, typename... Us>
struct has_type<T, std::tuple<Us...>> : std::disjunction<std::is_same<T, Us>...> {};
template <typename T, typename... Us>
inline constexpr bool has_type_v = has_type<T, Us...>::value;
struct foo_tag{};
struct bar_tag{};
struct AllGroup
{
using List = std::tuple<foo_tag, bar_tag>;
};
struct FooGroup
{
using List = std::tuple<foo_tag>;
};
template<class Group>
class log
{
public:
template<typename T = foo_tag>
std::enable_if_t<std::is_same_v<T, foo_tag> && has_type_v<foo_tag, typename Group::List>>
foo() { std::cout << "do foo\n"; }
template<typename T = foo_tag>
std::enable_if_t<std::is_same_v<T, foo_tag> && !has_type_v<foo_tag, typename Group::List>>
foo() { std::cout << "do nothing instead foo\n"; }
template<typename T = bar_tag>
std::enable_if_t<std::is_same_v<T, bar_tag> && has_type_v<bar_tag, typename Group::List>>
bar() { std::cout << "do bar\n"; }
template<typename T = bar_tag>
std::enable_if_t<std::is_same_v<T, bar_tag> && !has_type_v<bar_tag, typename Group::List>>
bar() { std::cout << "do nothing instead bar\n"; }
};
int main()
{
log<FooGroup> foo;
foo.foo();
foo.bar();
log<AllGroup> all;
all.foo();
all.bar();
}
Выведет:
do foo
do nothing instead bar
do foo
do bar
Про C++11 я забыл как про страшный сон))). По крайней мере большую часть того что выше написано, в C++11 можно заменить с помощью boost::mpl
Идея в том, чтобы можно было задать фильтры, и вызовы логера с ненужными тегами превратились в пустые функции
Еще условия в enable_if_t
поменять на противоположные)
Статик в теге пробовал. Та же фигня с линкером.
Юзай наследование:
class LogFooGroup : public log<FooGroup> ...
Оно должно помочь.