【问题标题】:C2276 or C3867 compiler errors in C++C++ 中的 C2276 或 C3867 编译器错误
【发布时间】:2019-05-11 05:39:57
【问题描述】:

我需要将一个类成员函数“curve”发送到另一个函数“fun”,但在编译过程中出现错误。如何正确编码?

使用地址“&”导致 C2276,不使用它 - C3867。

class Test
{
public:
    double v;

    double curve(double x)
    {
        return x + v;
    }

    Test(double z)
    {
        v = z;
    }
};

double fun(double(*f)(double), double x)
{
    return f(x);
}

void main()
{
    Test d(2.0);

    double r = fun(&d.curve, 3.0);
}

【问题讨论】:

  • 可能需要使用std::bind,或者更好的是,只需调用函数的 lambda。
  • 好的,我试过 auto f = [&](double x) {return d.curve(x); }; double r = fun(f, 3.0); 但这会导致 C2664

标签: c++ class compiler-errors


【解决方案1】:

curveTest 类的成员函数,因此您需要有一个Test 的实例,在该实例上可以调用curve

您可以更改fun 以将第一个参数指针作为成员函数的指针,并将第二个参数传递给Test 实例的引用,结果代码可能如下所示:

class Test {
public:
    double v;

    double curve(double x) {
        return x + v;
    }

    Test(double z) {
        v = z;
    }
};

double fun(  double(Test::*f)(double)  , Test& obj, double x) {
    return (obj.*f)(x);
}

int main()
{
    Test d(2.0);
    double r = fun(&Test::curve, d, 3.0);
}

【讨论】:

    【解决方案2】:

    如果可以改fun签名,rafix07的回答就完美了。

    如果你不想改变fun的参数个数,你可能想这样写:

    double fun(double(*f)(double), double x)
    {
        return f(x);
    }
    
    int main() // not void
    {
        Test d(2.0);
        double r = fun([d](double double_){ return d.curve(double_); }, 3.0);
        std::cout << r;
    }
    

    遗憾的是它不起作用,因为只有在不使用捕获的情况下,lambda 才能存储在函数指针中。

    所以你有两个解决方案:

    1) 模板

    // Must be in .hpp
    template <class T>
    double fun(T f, double x)
    {
        return f(x);
    }
    
    int main() // not void
    {
        Test d(2.0);
        double r = fun([d](double double_) mutable { return d.curve(double_); }, 3.0);
    }
    

    2) std::function

    #include <functional>
    double fun(std::function<double(double)> f, double x)
    {
        return f(x);
    }
    

    注意:你必须使用mutable,因为double curve(double x)不是const,我认为应该是。

    【讨论】:

    • 好的,当我使用 CLR 控制台应用程序时,第二个解决方案可以完美运行。在我的主 CLR 项目中尝试此行后,我收到 C3923 错误(“成员”:托管类的成员函数中不允许本地类、结构或联合定义)。该函数看起来像Matrix integrate(std::function&lt;double(double)&gt; f, unsigned steps, unsigned substeps, double end, double start = 0.0) {...},我称之为Input d; Matrix r = integrate([d](double double_) mutable { return d.curvature(double_); }, 100, 10, 3.1416 / 2.0);
    • 好吧,你可以试试 rafix07 的解决方案,因为它没有 lambda(lambda 是匿名类)。 AFAIK 看起来像是视觉工作室的错误/限制。您可能应该关闭此问题(因为您描述的问题已解决)并使用 visual-studio 标签和您拥有的所有信息打开一个新问题
    猜你喜欢
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-05
    • 1970-01-01
    • 1970-01-01
    • 2013-05-03
    相关资源
    最近更新 更多