Не могу использовать сложные функции C ++ в std :: function # 2 - PullRequest
0 голосов
/ 09 апреля 2020

Предыдущий вопрос

По неизвестным мне причинам мой код перестал работать сегодня. Для предварительно реализованных функций у меня есть такой код реле

Math_Node& Function_Manager::relay_complex_to_std(Math_Node& arg, std::function<Complex(const Complex&)> f) const{
    if( arg.children_.size() != 1 ){
        throw std::runtime_error("Function expects exactly one argument.");
    }
    evaluate(*arg.children_[0]);
    if( std::holds_alternative<Complex>(arg.children_[0]->data_) ){
        arg.data_ = f(std::get<Complex>(arg.children_[0]->data_));
        arg.children_.clear();
    }
    return arg;
}

с типами

using Decimal       = double;
using Complex       = std::complex<Decimal>;

. Его можно вызывать с помощью другой функции, например

Math_Node& Function_Manager::sqrt(Math_Node& arg) const{
    //return relay_complex_to_std(arg, std::sqrt<Complex::value_type>);
    return relay_complex_to_std(arg, [](Complex a){return std::sqrt(a);});
}

. строка комментария перестала работать с сообщением об ошибке

In member function ‘Numeric_Calculator::Math_Node& Numeric_Calculator::Function_Manager::sqrt(Numeric_Calculator::Math_Node&) const’:
functionmanager.cpp:214:72: error: 
no matching function for call to ‘Numeric_Calculator::Function_Manager::relay_complex_to_std(Numeric_Calculator::Math_Node&, unresolved overloaded function type>) const’
         return relay_complex_to_std(arg, std::sqrt<Complex::value_type>);

Почему тип функции не разрешен? Он работает, когда я помещаю его в лямбду.

Компилятор:

g ++ - 9 - версия
g ++ - 9 (Ubuntu 9.2.1-17ubuntu1 ~ 18.04.1 ) 9.2.1 20191102

edit:

Спасибо Jarod42 за указание на перегрузку с valarray. Вы можете убедиться, что удаление комментария в строке ниже приведет к той же ошибке

#include <cmath>
#include <complex>
#include <functional>
#include <iostream>
//#include <valarray>

using Complex = std::complex<double>;

Complex relay(Complex arg, std::function<Complex(Complex)> f){
    return f(arg);
}

int main(){
    std::function<Complex(Complex)> f = std::sqrt<Complex::value_type>;
    std::cout << std::sqrt(4.0) << "\n";
    std::cout << relay(Complex(-2,0), std::sqrt<Complex::value_type>) << "\n";
    return 0;
}

1 Ответ

1 голос
/ 09 апреля 2020

std::sqrt<double> может быть неоднозначным, это может быть

И тогда как std::complex можно преобразовать в ожидаемое std::function, разрешение имен не учитывает это преобразование.

См. Адрес перегруженной функции для получения более подробной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...