c++ - How to select the right overloaded function template at compile-time? -
i'm trying understand how select right overloaded function template @ compile-time, compiler giving me hard time. can make work, don't understand going on. let me explain.
i have 2 structs , b below. 1 has special function , other normal.
struct { void special() { std::cout << "special called.\n"; } }; struct b { void normal() { std::cout << "normal called.\n"; } };
my intension have mechanism, @ compile-time selects right overloaded function template depending on if special function available. have 2 functions run, take struct parameter, can call appropriate function.
template<class func, func f> struct sfinae {}; template <typename u> static void run(u& u, sfinae<void (u::*)(), &u::special>* = 0) { u.special(); } template <typename u> static void run(u& u, ...) { u.normal(); }
i've tested following, various results:
int main() { a; run<a>(a, 0); // works run<a>(a); // error: ambiguous overloaded function run(a, 0); // error: has no member normal run(a); // error: ambiguous overloaded function b b; run<b>(b, 0); // works run<b>(b); // works run(b, 0); // works run(b); // works return 0; }
i'd use run(a)
without argument or <>. there wrong code when not working?
also, i'm interested understand going on here , why deducing things this, need give <a>
a
not b
? don't know standard says , if different between compilers, @ least gcc4.4.4 on linux , gcc 4.0.1 on mac work i've described.
can please shed light on this? thanks!
this here work. sort-of assumes 2 functions normal , special mutually exclusive (i.e. class has 1 of them doesn't have other). i'm sure can adapt purpose. uses boost::enable_if
, of course.
#include <iostream> #include <boost/utility/enable_if.hpp> struct { void special() { std::cout << "special called.\n"; } }; struct b { void normal() { std::cout << "normal called.\n"; } }; template<int> struct sfinae { enum { value = true }; }; template <typename u> static typename boost::enable_if<sfinae<sizeof(&u::special)>,void>::type run(u& u) { u.special(); } template <typename u> static typename boost::enable_if<sfinae<sizeof(&u::normal)>,void>::type run(u& u) { u.normal(); } int main() { a; run(a); // works b b; run(b); // works return 0; }
this works on gcc 4.6.0 on linux.
Comments
Post a Comment