简体   繁体   English

如何在 class 模板的成员 ZC1C425268E68385D1AB5074C14 中正确调用 function object 正在生成 Visual Studio 编译器错误 C2440

[英]How to properly invoke a function object within a class template's member function? Visual Studio Compiler Error C2440 is being generated

This is a follow up to this question found here !这是对此处找到的这个问题的后续行动!

Now, that I'm able to instantiate the object.现在,我可以实例化 object。 I'm now getting a Visual Studio C2440 Compiler Error...我现在收到 Visual Studio C2440 编译器错误...


In my original code before it was templated I had a set of member functions that worked on the std::function<double(double)> member object that looked like this:在模板化之前的原始代码中,我有一组在std::function<double(double)>成员 object 上工作的成员函数,如下所示:

struct SomeStruct {
    double a_;
    double b_;
    SomeStruct(double a, double b) : a_{a}, b_{b} {}
};

class SomeClass {
private:
    SomeStruct fields_;
    size_t n_;
    std::function<double(double)> func_;

public:
    SomeClass(SomeStruct fields, size_t n, std::function<double(double)> func) :
      fields_{fields}, n_{n}, func_{func}
    {}

    double evaluate() {
        auto distance = fields_.a_ - fields_.b_;  
        auto dx = distance / n_;
        return calculate(dx, fields_);
    }

private:
    double calculate(double dx, const SomeStruct& someStruct) {
        double result = 0;
        for (size_t i = 0; i < n_; ++i) {
            auto dy = func_(someStruct.a_ + i * dx);
            auto area = dy * dx;
            result += area;
        }
        return result;
    }
};

Now my class looks like this:现在我的 class 看起来像这样:

template<typename Field>
struct SomeStruct {
    Field a_;
    Field b_;
    constexpr SomeStruct(Field a, Field b) : a_{a}, b_{b} {}
};

template<typename FieldType, typename ValueType, typename Func>
class SomeClass {
private:
    SomeStruct<FieldType> fields_;
    size_t n_;
    Func func_; 

public:
    SomeClass(SomeStruct<FieldType> fields, size_t n, Func func) :
        fields_{fields}, n_{n}, func_{func}
    {}

    constexpr ValueType evaluate() {
        auto distance = fields_.a_ - fields_.b_;       
        auto dx = distance / n_;              
        return calculate(dx, fields_);
    }

private:
    constexpr ValueType calculate(ValueType dx, const SomeStruct<FieldType>& someStruct) {
        ValueType result = 0;
        for (size_t i = 0; i < n_; ++i) {
            auto dy = func_(someStruct.a_ + i * dx);
            auto area = dy * dx;
            result += area;
        }
        return result;
    }
};

template<typename FieldType, typename ValueType, typename Func>
SomeClass(SomeStruct<FieldType>, ValueType, Func) ->
SomeClass<FieldType, ValueType, Func>;

I'm now trying to use the class as such:我现在正在尝试使用 class :

template<typename T>
constexpr T funcA(T x) {
    return x;
}

template<typename T>
constexpr T funcB(T x) {
    return x*x;
}

int main() {
    SomeClass a{SomeStruct{1.0, 3.0}, 1000, &funcA<double>};
    // a.evaluate();

    SomeClass b{SomeStruct{3.5, 7.5}, 2000, &funcB<double>};
    // b.evaluate();
    return 0;
}

And I'm getting this Visual Studio error...我收到了这个 Visual Studio 错误...

1>------ Build started: Project: Computations, Configuration: Debug Win32 ------
1>main.cpp
1>c:\users\...\main.cpp(33): error C2440: 'initializing': cannot convert from 'initializer list' to 'Integrator<double,int,T (__cdecl *)(T)>'
1>        with
1>        [
1>            T=double
1>        ]
1>c:\users\...\main.cpp(33): note: No constructor could take the source type, or constructor overload resolution was ambiguous
1>Done building project "Computations.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

This is being generated before I even call its public evaluate() function that will call its private calculate() function...这是在我什至调用它的公共evaluate() function 之前生成的,它将调用它的私有calculate() function ...

I'm trying to resolve this compiler error, and I'm trying to make sure that I'm able to invoke the function object, function pointer, functor, lambda that is stored within this class properly... I'm trying to resolve this compiler error, and I'm trying to make sure that I'm able to invoke the function object, function pointer, functor, lambda that is stored within this class properly...

The problem is in the declaration of data member Func :问题出在数据成员Func的声明中:

Func* func_; 

It declares func_ to be of a pointer to the type deduced by a deduction guide:它将func_声明为指向由推导指南推导的类型的指针

template <typename FieldType, typename ValueType, typename Func>
SomeClass(SomeStruct<FieldType>, ValueType, Func)
    -> SomeClass<FieldType, ValueType, Func>;

By calling the constructor with an address of a function:通过使用 function 地址调用构造函数:

SomeClass a{SomeStruct{1.0, 3.0}, 1000, &funcA<double>};

Func is deduced as:函数Func为:

Func = double(*)(double)

Thus, Func* becomes a pointer to a function pointer:因此, Func*成为指向 function 指针的指针:

Func* = double(**)(double)

and that cannot be initialized with &funcA<double> .并且不能用&funcA<double>初始化。 Instead, use Func alone as the data member type.而是单独使用Func作为数据成员类型。


I'm trying to make sure that I'm able to invoke the function object, function pointer, functor, lambda that is stored within this class properly I'm trying to make sure that I'm able to invoke the function object, function pointer, functor, lambda that is stored within this class properly

Either use a concept for that or a static assert:要么为此使用一个概念,要么使用 static 断言:

static_assert(std::is_invocable_v<Func&, FieldType&>, "Invalid callable");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM