相关疑难解决方法(0)

C++可以编译内联函数指针吗?

假设我有一个functionProxy带有泛型参数的函数function并调用它operator():

template< typename Function > void functionProxy( Function function ) {
    function();
}
Run Code Online (Sandbox Code Playgroud)

传递给它的对象可能是:


int main( )
{
    functionProxy( Functor() );
    functionProxy( function );
    functionProxy( [](){ std::cout << "lambda!" << std::endl; } );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器将能够内联function中 …

c++ compiler-construction optimization inline function

27
推荐指数
1
解决办法
9959
查看次数

将函数作为显式模板参数传递

在下面的代码示例中,调用foo工作,而调用bar失败.

如果我注释掉调用bar,代码编译,告诉我自己的定义bar是好的.那怎么会bar被正确调用?

#include <iostream>

using namespace std;

int multiply(int x, int y)
{
    return x * y;
}

template <class F>
void foo(int x, int y, F f)
{
    cout << f(x, y) << endl;
}

template <class F>
void bar(int x, int y)
{
    cout << F(x, y) << endl;
}

int main()
{
    foo(3, 4, multiply); // works
    bar<multiply>(3, 4); // fails

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ templates

20
推荐指数
2
解决办法
1万
查看次数

函数类型可以是类模板参数吗?

下面的代码被VC++ 2012拒绝,"错误C2207:'A :: bar':类模板的成员无法获取函数类型".

int Hello(int n)
{
    return n;
}

template<class FunctionPtr>
struct A
{
    A(FunctionPtr foo)
        : bar(foo)
    {}

    FunctionPtr bar;
};

int main()
{
    A<decltype(Hello)> a(Hello);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么?

c++ templates c++11

16
推荐指数
2
解决办法
3644
查看次数

我可以使用C++ 17 captureless lambda constexpr转换运算符的结果作为函数指针模板非类型参数吗?

在回答时如何编写看起来像方法的lambda表达式?我试图通过利用这样一个事实将无捕获的lambda变成一个成员函数指针,因为C++ 17,无捕获的lambdas有一个constexpr转换操作符到它们的函数指针类型.

所以我提出了一个问题:

template<void(*)()> struct A{};

int main()
{
  A<static_cast<void(*)()>([]{})>{}; // 1

  constexpr auto fp = static_cast<void(*)()>([]{});
  A<fp>{}; // 2
}
Run Code Online (Sandbox Code Playgroud)

现在,这在clang(从5.0.0开始)编译,但gcc(> = 7.2)抱怨:

error: lambda-expression in template-argument
   A<static_cast<void(*)()>([]{ /*whatever*/ })>{}; // 1
                            ^
error: 'main()::<lambda()>::_FUN' is not a valid template argument for type 'void (*)()' because 'static constexpr void main()::<lambda()>::_FUN()' has no linkage
   A<fp>{}; // 2
Run Code Online (Sandbox Code Playgroud)

问题是,谁是对的?

c++ lambda templates language-lawyer c++17

12
推荐指数
1
解决办法
765
查看次数

我如何将lambda表达式作为参数传递给c ++模板

我有一个接受函数作为参数的模板.

当我尝试传递lambda表达式时,它不会编译.

typedef int (*func)(int a);
template <func foo>
int function(int a)
{
    foo(a);
}

int test(int a)
{
    return a;
}

int main()
{
    function<test>(1);   // ---> this is ok

    auto lambda = [](int a) -> int { return a; };
    function<lambda>(1); // ---> this is wrong, why?

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

c++ lambda templates

10
推荐指数
3
解决办法
8431
查看次数

C++函数调用包装器,函数作为模板参数

我正在尝试创建一个通用的包装器函数,它将函数作为模板参数,并使用与该函数相同的参数作为其参数.例如:

template <typename F, F func>
/* return type of F */ wrapper(Ts... Args /* not sure how to get Ts*/)
{
    // do stuff
    auto ret = F(std::forward<Ts>(args)...);
    // do some other stuff
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

解决方案需要可以转换为具有相同类型的函数指针,func以便我可以将其传递给C api.换句话说,解决方案需要是一个函数而不是一个函数对象.最重要的是,我需要能够在包装函数中完成工作.

如果内联评论不清楚,我希望能够做如下的事情:

struct c_api_interface {
    int (*func_a)(int, int);
    int (*func_b)(char, char, char);
};

int foo(int a, int b)
{
    return a + b;
}

int bar(char a, char b, char c)
{
    return a + b * c; …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic-functions variadic-templates

9
推荐指数
2
解决办法
3974
查看次数

函数/仿函数作为模板参数.他们可以存储吗?

想象一下,我有以下免费功能和仿函数:

void myFreeFunction(void)
{
    cout << "Executing free function" << endl;
}

struct MyFunctor
{
    void operator()(void)
    {
        cout << "Executing functor" << endl;
    }
};
Run Code Online (Sandbox Code Playgroud)

正如这个答案所描述的,我可以将我的函数或仿函数作为模板参数传递给另一个函数:

template <typename F>
void doOperation(F f)
{
    f();
}
Run Code Online (Sandbox Code Playgroud)

然后打电话:

doOperation(myFreeFunction);
doOperation(MyFunctor());
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.但是,如果我想要以下内容:

template<typename Callback>
class MyClass
{
private:
    Callback mCallback;

public:
    MyClass(){}

    void execute()
    {
        mCallback();
    }
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我在声明类时指定函数/函子,但是直到稍后才调用它.它适用于仿函数:

MyClass<MyFunctor> myClass1;
myClass1.execute();
Run Code Online (Sandbox Code Playgroud)

但不适用于功能:

MyClass<myFreeFunction> myClass2;
myClass2.execute();
Run Code Online (Sandbox Code Playgroud)

编译说:

错误C2923:'MyClass':'myFreeFunction'不是参数'Callback'的有效模板类型参数

这是公平的......但你会如何构建这个?

注意:我知道std :: function并且最终可能会使用它.它虽然速度慢得多,但我正在考虑所有选择.

谢谢,

大卫

c++ templates callback

7
推荐指数
1
解决办法
1万
查看次数

为什么很清楚模板函数实例化不会内联?

关于作为模板参数传递的函数,Ben Supnik提供的社区wiki答案讨论了内联实例化函数模板的问题.

在那个答案是以下代码:

template<typename OP>
int do_op(int a, int b, OP op)
{
  return op(a,b,);
}

int add(int a, b) { return a + b; }

int (* func_ptr)(int, int) = add;

int c = do_op(4,5,func_ptr);
Run Code Online (Sandbox Code Playgroud)

答案继续这样说(关于实例化函数模板的最后一行do_op):

显然这不是内联.

我的问题是:为什么很明显这不是内联的?

c++ templates

7
推荐指数
1
解决办法
1144
查看次数

传递运算符作为函数模板参数

我必须为我制作的一些非常复杂的对象重载基本的算术运算符.到目前为止,我已成功实施operator*; 现在我需要operator+等等.代码operator*非常大,但是operator*operator+我之间的唯一区别在于我使用的一行+而不是*一些复杂的数字.这一行将在一个被多次调用的循环内部,所以我希望它有效,这似乎意味着没有函数指针.(如我错了请纠正我.)

这似乎是模板的完美用法.但我对正确的语法感到茫然.我在ComplicatedObject类定义中思考这样的事情:

template <typename ComplexBinaryOp>
ComplicatedObject BinaryOp(const ComplicatedObject& B) const {
  // Do lots of stuff
  for(unsigned int i=0; i<OneBazillion; ++i) {
    // Here, the f[i] are std::complex<double>'s:
    C.f[i] = ComplexBinaryOp(f[i], B.f[i]);
  }
  // Do some more stuff
  return C;
}

inline ComplicatedObject operator*(const ComplicatedObject& B) const {
  return BinaryOp<std::complex::operator*>(B);
}

inline ComplicatedObject operator+(const ComplicatedObject& B) const {
  return BinaryOp<std::complex::operator+>(B);
}
Run Code Online (Sandbox Code Playgroud)

这个问题是相关的:"作为模板参数传递的函数" …

c++ templates operator-overloading

7
推荐指数
1
解决办法
2236
查看次数

C++将变量转换为模板参数

我想描述使用模板优化这里.但是,随着bool模板参数的增加,实例化模板可能会有太多分支.如果你使用更大的枚举而不是bools,它会变得更加冗长.

#include <iostream>
using namespace std;

template <bool b1, bool b2>
int HeavyLoop_impl(int arg)
{
    for (int i = 0; i < 10000000; i++)
    {
        // b1 is known at compile-time, so this branch will be eliminated
        if (b1) { arg += 1; }
        else    { arg += 2; }

        // b2 is known at compile-time, so this branch will be eliminated
        if (b2) { arg += 10; }
        else    { arg += 20; }
    }
    return arg; …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11

7
推荐指数
1
解决办法
2006
查看次数