Здравствуйте, szag, Вы писали:
Во-первых, кажется, что typename в некоторых местах лишний, ну и "если гора не идет к Магомету, то Магомет идет к горе": S>Есть вот такой код:
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/typeof/std/utility.hpp>
#include <vector>
template<class T>
struct foo : public T
{
typedef typename BOOST_TYPEOF(&T::f) f_type; // error C2039: 'f': is not a member of 'bar'typedef typename boost::function_types::parameter_types<f_type> parameter_types;
typedef typename boost::mpl::at_c< parameter_types, 1>::type vec_type;
std::vector<vec_type> vec;
};
struct bar
{
void f (int i){}
};
int main()
{
foo<bar> b;
return 0;
}
Re[2]: Использовать тип параметра функции в предке
Здравствуйте, Warturtle, Вы писали:
W>Здравствуйте, szag, Вы писали: W>Во-первых, кажется, что typename в некоторых местах лишний, ну и "если гора не идет к Магомету, то Магомет идет к горе":
это понятно, но так не подходит. Если бы работал вариант, который показал я, то он бы просто идеально вписался в проект, добавивив неоходимый функционал без каких-либо изменений в остальном проекте.
template<typename tp_Derived> class
bar_base;
template<class T>
class foo
{
public:
typedef typename BOOST_TYPEOF(&bar_base<T>::f) f_type;
typedef typename boost::function_types::parameter_types<f_type> parameter_types;
typedef typename boost::mpl::at_c< typename parameter_types, 1>::type vec_type;
std::vector<typename vec_type> vec;
};
template<typename tp_Derived> class
bar_base
{
public: void f (int i){} // возможно вызывает настоящий метод в bar
};
class bar : public bar_base<bar>, public foo<bar>
{
};
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[2]: Использовать тип параметра функции в предке
Здравствуйте, VTT, Вы писали:
VTT>Может CRTP поможет?
идеальный вариант — это не трогать клалас бар вообще, а вот с фуу можно делать все что угодно. Структура многих проектов такая, что от фуу наследуется вного разных бар, поэтому менять в куче мест сами бары не хотелось бы.
Re[3]: Использовать тип параметра функции в предке
Здравствуйте, szag, Вы писали:
S>Здравствуйте, Warturtle, Вы писали:
W>>Здравствуйте, szag, Вы писали: W>>Во-первых, кажется, что typename в некоторых местах лишний, ну и "если гора не идет к Магомету, то Магомет идет к горе": S>это понятно, но так не подходит. Если бы работал вариант, который показал я, то он бы просто идеально вписался в проект, добавивив неоходимый функционал без каких-либо изменений в остальном проекте.
Значит надо уточнить почему не годится. Так не вполне ясно, чего ты хочешь. Зачем там обязательно наследование от foo<bar>? Например без него все и сейчас функционирует:
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/typeof/std/utility.hpp>
#include <vector>
#include <stdio.h>
#include <typeinfo>
template<class T>
class foo
{
public:
typedef typename BOOST_TYPEOF(&T::f) f_type; // error C2039: 'f': is not a member of 'bar'typedef typename boost::function_types::parameter_types<f_type> parameter_types;
typedef typename boost::mpl::at_c< parameter_types, 1>::type vec_type;
std::vector<vec_type> vec;
};
class bar
{
typedef foo<bar> FooT;
public:
void f (int i)
{
printf("f(%d), vec_type='%s'\n", i, typeid(FooT::vec_type).name());
}
};
int main()
{
bar b;
b.f(123);
return 0;
}
Re[4]: Использовать тип параметра функции в предке
W>Значит надо уточнить почему не годится. Так не вполне ясно, чего ты хочешь. Зачем там обязательно наследование от foo<bar>? Например без него все и сейчас функционирует:
template<class T>
class foo
{
public:
typedef typename BOOST_TYPEOF(&T::f) f_type; // сейчас этот тип захардкожен, поэтому все работает, но хочется гибкостиtypedef typename boost::function_types::parameter_types<f_type> parameter_types;
typedef typename boost::mpl::at_c< parameter_types, 1>::type vec_type;
void dispatch() // вызывает сам класс foo когда ему это надо
{
auto v = vec[0]; // псевдокод получения значения из вектораstatic_cast<T*>(this)->f(v);
}
void push(const vec_type& v)
{
vec.emplace_back(v);
}
std::vector<vec_type> vec;
};
class bar : public foo<bar> // таких классов по коду очень много, не хотелось бы их менять
{
public:
void f (int i){} // обработка значений
};
Здравствуйте, szag, Вы писали:
S>идеальный вариант — это не трогать клалас бар вообще, а вот с фуу можно делать все что угодно. Структура многих проектов такая, что от фуу наследуется вного разных бар, поэтому менять в куче мест сами бары не хотелось бы.
Судя по коду, требуется параметризовать foo типом первого (и единственного) аргумента bar::f.
Проще всего, в таком случае, передавать тип явно:
template<class CrtpFinal, class Arg>
class foo {
std::vector<Arg> vec_;
...
};
class bar : public foo<bar, int> {
void f(int);
};
Либо избавляться от наследования.
Ведь у неполных типов две беды: рекурсивное использование имён и рекурсивная зависимость лэяутов.
template<class Y> class x {
dependent_on<Y> v;
using z = Y::t;
};
class y : x<y> {
using t = derivative_of<z>;
};
Но если с именами это, прежде всего, вопрос чистоты рук, то на лэяут компилятор возмущается сразу и бесповоротно.
Поэтому делаем так:
#include <memory>
#include <vector>
using namespace std;
template<class Fun> struct first_arg_getter;
template<class R, class A, class... Aaa> struct first_arg_getter<R(*)(A,Aaa...)> {
using type = A;
};
template<class C, class R, class A, class... Aaa> struct first_arg_getter<R(C::*)(A,Aaa...)> {
using type = A;
};
#define FIRST_ARG_TYPE(fun) typename first_arg_getter<decltype(fun)>::type
template<class BAR> struct argvecs {
using fx = FIRST_ARG_TYPE(&BAR::f);
using gx = FIRST_ARG_TYPE(&BAR::g);
std::vector<fx> fxs_;
std::vector<gx> gxs_;
};
template<class BAR> struct foo {
using aaa = argvecs<BAR>;
std::unique_ptr<aaa> aaa_; // экстерриториальность спасает!
foo() : aaa_(new aaa()) {}
};
struct bar : foo<bar> {
static void f(int,char);
void g(long,short);
};
int main() {
bar b;
}
Перекуём баги на фичи!
Re[4]: Использовать тип параметра функции в предке