Ошибка замены не является ошибкой или, более компактно, SFINAE
Но в вашем конкретном случае вам не нужны SFINAE, виртуальные участники или что-то подобное.
Вам просто нужна обычная перегруженная функция.
int GetInt(A& t) { return t.GetInt(); }
int GetInt(const B& t) { return t.m; }
Если есть код, который необходимо совместно использовать в разных версиях, реорганизуйте его так, чтобы был шаблон, который вызывает перегруженную встроенную функцию, все поведение, зависящее от типа, находится во встроенной функции, а все общее поведение - в шаблоне.
Для вашей потребности "У меня много, много классов" SFINAE будет выглядеть примерно так:
template<typename T>
int GetInt(const T& t, int (T::*extra)() const = &T::GetInt)
{
return t.GetInt();
}
template<typename T>
auto GetInt(const T& t) -> decltype(t.m)
{
return t.m;
}
РЕДАКТИРОВАТЬ: Реальность SFINAE намного уродливее, по крайней мере, до тех пор, пока не появится C ++ 0x. Фактически, он начинает выглядеть так же плохо, как и ответ GMan.
struct A{ int GetInt() const { return 10; } };
struct B{ int m; };
template<typename T, int (T::*extra)() const>
struct has_mfunc
{
typedef int type;
};
template<typename T>
typename has_mfunc<T, &T::GetInt>::type GetInt(const T& t)
{
return t.GetInt();
}
template<typename T, typename U, U (T::*extra)>
struct has_field
{
typedef U type;
};
template<typename T>
typename has_field<T, int, &T::m>::type GetInt(const T& t)
{
return t.m;
}
int main(void)
{
A a;
B b;
b.m = 5;
return GetInt(a) + GetInt(b);
}
person
Ben Voigt
schedule
19.10.2010
GetInt
экземплярами, имеютint
член с именемm
, я не понимаю, как вы можете расширить это без специализации для каждого. Какова реализация вашего шаблона функции по умолчанию? - person Steve Townsend   schedule 19.10.2010GetInt
не const, аt
. - person GManNickG   schedule 19.10.2010