Search code examples
c++templatesc++14sfinaedecltype

SFINAE check for template parameter operators


Could you tell me why the following code fails to compile (with "no matching overloaded function found" in MSVC):

template<typename V>
struct LinearModel { // has basis vectors
    template<typename T = V>
    auto consolidation() const -> decltype(std::declval<T>() += (std::declval<T>() *= double())) {
        V linearCombination;
        // linearly combine basis vectors using += and *=
        return linearCombination;
    }
};

int main(){
    LinearModel<double> lm;
    auto c = lm.consolidation(); // the line that produces the error
    return 0;
}

My intention is to define LinearModel<T>::consolidation() only for T that have T& operator *=(double) and T& operator +=(T).


Solution

  • declval for T returns T&&, it is not allowed to assign result of *= (or other assignment operations) to R-value.

    If you want to get Lvalue use: declval<T&>():

        -> std::remove_reference_t<decltype(std::declval<T&>() += (std::declval<T&>() *= double{}))> 
    

    Live demo