Lambda函数无法调用函数模板参数的静态函数

时间:2011-11-13 16:55:23

标签: c++ c++11 lambda type-parameter

好的,所以我有一些基本上像这样的设置:

template<typename T> void example()
{
 std::function<int (byte*)> test = [=](byte* start) -> int
 {
  return T::magic(start);
 }
}

忽略“不洁净”如何进行这些裸体调用,它也无法编译,从而产生以下错误:

'T' : is not a class or namespace name
'magic': identifier not found

有没有办法能够在泛型类型名称T上进行调用,假设我将始终使用具有函数magic(byte * start)的类调用example()?当然,我不必为将要执行此操作的每个类重新声明此模板函数。

我在VC ++ 2010中这样做,看起来它可能是编译器错误。任何可能的解决方法?

3 个答案:

答案 0 :(得分:4)

唯一的错误是缺少分号。一旦修复,它就可以正常工作。

#include <iostream>
#include <functional>

typedef unsigned char byte;

template<typename T> void example()
{
    std::function<int (byte*)> test = [=](byte* start) -> int
    {
        return T::magic(start);
    }; // <--------------------------------- You were missing that
}

struct Foo {
    static int magic(byte*);
};

int Foo::magic(byte* start)
{
    std::cout << "magic\n";
}

int main()
{
    example<Foo>();
}

http://ideone.com/dRdpI

由于这似乎是VC10的lambda实现中的一个错误,一个可能的解决方法是创建一个本地仿函数类:

template<typename T> void example()
{
    struct Foo {
        int operator()(byte * start) { return T::magic(start); }
    };

    std::function<int (byte*)> test = Foo();    
}

答案 1 :(得分:3)

我用VS2010重现了这个问题。您需要来调用example函数,但是:

#include <functional>

struct SomeT { static int magic(unsigned char*) { return 42; } };

template<typename T> void example()
{
    std::function<int (unsigned char*)> test = [=](unsigned char* start) -> int
    {
        return T::magic(start);
    };
}

int main()
{
    example<SomeT>();
}

更新根据OP的评论:

这有效:

#include "stdafx.h"
#include <functional>

struct SomeT { static int magic(unsigned char*) { return 42; } };

template<typename T> void example()
{
    auto func = T::magic;
    std::function<int (unsigned char*)> test = [=](unsigned char* start) -> int
    {
        return func(start);
    };
}

int main()
{
    example<SomeT>();
}

我一直在寻找解决方法,但没有工作,我尝试了包括这个很好的排列,但还没有运气:

template<typename T> void example()
{
    static const T* workaround;
    std::function<int (unsigned char*)> test = [=](unsigned char* start) -> int
    {
        typedef decltype(*workaround) innerT;
        return innerT::magic(start);
    };
}

这个很难......

答案 2 :(得分:0)

我确定你做错了,因为我能够使用lambda中的语法T::f()来调用静态方法:

#include <iostream>
#include <functional>
struct A
{
   static void f() { std::cout << "called" << std::endl; }
};

template<typename T> 
void example()
{
  std::function<void()> test = [=]() { T::f(); };
  test();
}
int main() {
        example<A>();
        return 0;

}

演示:http://ideone.com/IPakS

所以请发布更多信息。直到这是答案。尝试将您的代码与此进行比较,看看您是否正在做一些非常错误的事情。

如果您正在使用GCC,是否使用-std=c++11选项编译代码?