這是不是爲什麼它不起作用的答案。然而,通過網絡進行研究,我發現了一些例子,並最終得到了下面的代碼,這可能會讓我更加努力。
我試圖檢測特定的成員函數簽名,但下面的代碼超越並檢測給定的調用是否可能,無論簽名是什麼。希望評論會有所幫助。
#include <iostream>
template< class T >
class has_apply {
class yes { char c; };
class no { yes c[2]; };
struct mixin {
void apply(void);
};
// Calling derived::apply is only non-ambiguous if
// T::apply does not exist, cf. 10.2.2.
template< class U> struct derived : public U, public mixin {};
// The following template will help on deduction based on this fact.
// If U is type void (mixin::*) (void) then the template can be
// instantiated with u = &derived<U>::apply if and only if T::apply
// does not exist.
template< class U, U u >
class binder {};
// Therefore, the following template function is only selected if there
// is no T::apply:
template< class U >
static no deduce(U, binder< void (mixin::*) (void), &derived<U>::apply >* = 0);
// Selected otherwise.
static yes deduce(...);
// Provides an T object:
static T T_obj(void);
public:
static const bool result = (sizeof(yes) == sizeof(deduce(T_obj())));
};
namespace aux {
// Class to represent the void type as a "true" type.
class void_type {};
// deduce() some lines below will give us the right answer based on
// the return type of T::apply<>, but if it is void we cannot use a
// call to T::apply as an argument to deduce. In fact, the only
// function in c++ that can take such an argument is operator,() with
// its default behaviour and if an overload is not well formed it
// falls back to default.
template< class T >
T& operator,(const T&, void_type) {};
// Copies the constness of T into U. This will be required in order
// to not get false positives when no const member is defined.
template< class T, class U >
struct copy_constness {
typedef U result;
};
template< class T, class U >
struct copy_constness< const T, U > {
typedef const U result;
};
}
template< class T >
class has_correct_apply{
class yes { char c; };
class no { yes c[2]; };
// We assume has_apply<T>::result is true so the following class
// is well declared. It is declared in a way such that a call to
// derived::apply<n>() is always possible. This will be necessary
// later.
struct derived : public T {
using T::apply; // possible iff has_apply<T>::result == true
// This template function will be selected if the function call
// we wish is otherwise invalid.
template< unsigned n >
static no apply(...);
};
// const_correct_derived will have the same constness than T.
typedef typename aux::copy_constness< T, derived >::result const_correct_derived;
// Provides a const correct derived object.
static const_correct_derived derived_obj(void);
// Only possible call was derived::apply: call is impossible for signature:
static no deduce(no);
// Since te returned value of it will most likely be
// ignored in our code (void must be always [almost, see next]
// ignored anyway), we return yes from this:
static yes deduce(...);
// As we noticed, an overload of operator,() may make an exact match necessary.
// If we want this we could simply have used "no" instead of "yes" above and:
// static no deduce(aux::void_type);
public:
static const bool result = (sizeof(yes) == sizeof(deduce(
(derived_obj().template apply<0u>(0.0), aux::void_type())
)));
// Note: Inteestingly enough, GCC does not detect an private subclass default
// constructor and so const_correct_derived() could be used instead of
// having a function derived_obj(), but I do not know if this behavoiur is
// standard or not.
};
struct C {
template< unsigned n >
int apply(double, unsigned m = 10) const;
private:
C();
};
struct D {
template< unsigned n >
int apply(const double&);
private:
D();
};
struct E : public C {
};
struct Without{};
#include "mp.h"
int main()
{
std::cout << has_apply<E>::result << '\n';
std::cout << has_correct_apply< const E >::result << '\n';
std::cout << has_correct_apply< const D >::result << '\n';
std::cout << has_correct_apply<D>::result << '\n';
// E e;
return(0);
}
你有可能簡化代碼嗎? (我敢肯定,你不需要所有7個'yes'模板來證明問題。)或者至少添加一些評論? – 2010-11-09 17:08:37
我已經添加了6個測試來涵蓋所有可能性,但奧利查爾斯沃思留下的測試應該足以產生「真實」。 – Elias 2010-11-09 17:48:08
是的,我冒險只有這一個是相關的。請隨時編輯適當的! – 2010-11-09 17:51:48