2015-09-06 2 views
0

Я пытаюсь автоматически сгенерировать функцию-функцию const с некоторыми шаблонами. Пожалуйста, помогите мне скомпилировать этот код.простая ошибка дедукции шаблона

template<typename T> 
struct Constifier 
{ 
    typedef T Type; 
}; 

template<typename T> 
struct Constifier<T &> 
{ 
    typedef const T &Type; 
}; 

template<typename T> 
struct Constifier<T &&> 
{ 
    typedef const T &&Type; 
}; 

template<typename T> 
struct Constifier<T *> 
{ 
    typedef const T *Type; 
}; 

template<typename F> 
struct ReturnType; 

template<typename R, typename ...Ts> 
struct ReturnType<R (*)(Ts ...ts)> 
{ 
    typedef R Type; 
}; 

template<typename R, typename T, typename ...Ts> 
struct ReturnType<R (T::*)(Ts ...ts)> 
{ 
    typedef R Type; 
}; 

template<typename T, typename F, typename ...Ts> 
auto callConstVersion(const T *t, F f, Ts ...ts) 
{ 
    return const_cast<typename Constifier<typename ReturnType<F>::Type>::Type>((const_cast<T *>(t)->*f)(ts...)); 
} 

struct A 
{ 
    A *p; 
    A *get() {return p;} 
    const A *get() const {return callConstVersion(this, &A::get);} 
}; 
+0

'get' перегружен, вам понадобится нечто вроде' static_cast (& A :: get) ' –

+0

@PiotrSkotnicki Я тоже думал об этом, но я не может мыслить способ отличить правильный перегруженный неконтакт '' get'. – xiver77

+0

@PiotrSkotnicki Я попробую это. – xiver77

ответ

1

Функция get члена перегружена, таким образом, дано &A::get в качестве аргумента, F становится не выводима. Для неоднозначности между двумя использовать static_cast:

static_cast<const A*(A::*)() const>(&A::get) // for the const overload 

static_cast<A*(A::*)()>(&A::get) // for the non-const overload 

или указать F явно в списке аргументов шаблона:

callConstVersion<A,A*(A::*)()>(this, &A::get); 

или если вы знаете callConstVersion всегда должен неконстантная энергонезависимую Непро- реф-квалифицированная функция, вы можете переопределить его следующим образом:

template<typename T, typename R, typename... Args, typename ...Ts> 
auto callConstVersion(const T *t, R(T::*f)(Args...), Ts ...ts) 

(тогда обычная callConstVersion(this, &A::get) должен работать).

Смежные вопросы