SFINAE проверка для операторов параметров шаблона - PullRequest
0 голосов
/ 23 января 2020

Не могли бы вы сказать мне, почему следующий код не компилируется (с "не найдена соответствующая перегруженная функция" в MSV C):

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;
}

Мое намерение - определить LinearModel<T>::consolidation() только для T, которые имеют T& operator *=(double) и T& operator +=(T).

Ответы [ 2 ]

2 голосов
/ 23 января 2020

declval для T возвращает T&&, нельзя присваивать результат *= (или другим операциям присваивания) для R-значения.

Если вы хотите получить Lvalue, используйте: declval<T&>():

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

Live демо

0 голосов
/ 23 января 2020

Что я сделал в конце, основываясь на ответе @ rafix07:

    template<typename T = std::remove_reference_t<decltype(std::declval<V&>() += (std::declval<V&>() *= double()))>>
    T consolidation() const {
        T linearCombination;
        // ...
        return linearCombination;
    }
...