c++ - type-deduction using auto for functors -


i relatively new c++11 features. have question regarding auto feature , how type-deduces functors. consider following code snippet:

bool test1(double a, double b) {    return (a<b); }     bool test2(double a, double b) {        return (a>b);    }     struct test1 {        bool operator()(double a, double b) {           return (a<b);        }    };     struct test2 {        bool operator()(double a, double b){           return (a>b);        }    };     int main() {        const bool ascending = false;        auto comparator =  ascending? test1:test2; // works fine       auto comparator2 = ascending? test1():test2(); // compiler error: imcompatible types       std::function<bool(double, double)> comparator3 = ascending? test1():test2(); // compiler error: imcompatible types;     } 

while auto (and std::function) works fine functions, fails (type-deduction) function objects. why this? missing fundamental w.r.t type-deduction here.

(i using visual studio 2012)

per paragraph 5.16/3 of c++11 standard on conditional (?) operator:

[...] if second , third operand have different types , either has (possibly cv-qualified) class type, or if both glvalues of same value category , same type except cv-qualification, attempt made convert each of operands type of other. [...] if both can converted, or 1 can converted conversion ambiguous, program ill-formed. [...]

in case, neither test1 nor test2 can converted other type. why compiler complaining "incompatible types".

nptice, if wasn't case, type of comparator2 , comparator3 determined @ run-time based on value of ascending. however, c++ statically-typed language, meaning the type of objects has determined @ compile-time.

if need perform run-time selection of comparator , hold result in 1 variable, consider first assigning both objects functor of same type can encapsulate them both, , then performing selection:

    std::function<bool(double, double)> c1 = test1();     std::function<bool(double, double)> c2 = test2();     auto c = (ascending) ? c1 : c2; 

Comments