Лямбда-функция не может вызывать статические функции параметра шаблона функции - PullRequest
6 голосов
/ 13 ноября 2011

Хорошо, у меня есть что-то вроде установки:

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, предполагая, что я всегда буду вызывать example () с классом, имеющим функцию magic (byte * start)?Конечно, мне не нужно повторно объявлять эту функцию шаблона для каждого отдельного класса, который будет это делать.

Я делаю это в VC ++ 2010, и, похоже, это может быть ошибка компилятора.Любые возможные обходные пути?

Ответы [ 3 ]

4 голосов
/ 13 ноября 2011

Единственная ошибка - пропущенная точка с запятой.Как только это будет исправлено, все будет работать нормально.

#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, возможный обходной путь - создать класс локального функтора:

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

    std::function<int (byte*)> test = Foo();    
}
3 голосов
/ 13 ноября 2011

Я воспроизвел проблему с 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>();
}

Обновление на основе комментария ОП:

Это работает:

#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);
    };
}

Жесткийодин этот ...

0 голосов
/ 13 ноября 2011

Я уверен, что вы делаете что-то не так, потому что я могу вызвать статический метод, используя синтаксис 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?

...