Reputation: 1840
Ok, so I have something setup basically like this:
template<typename T> void example()
{
std::function<int (byte*)> test = [=](byte* start) -> int
{
return T::magic(start);
}
}
Ignoring how "unclean" making these naked calls is, it also doesn't compile, giving these errors:
'T' : is not a class or namespace name
'magic': identifier not found
Is there any way to be able to make a call on the generic typename T, assuming I will always be calling example() with a class that has the function magic(byte* start)? Surely I don't have to redeclare this template function for every single class that will be doing this.
I'm doing this in VC++ 2010, and it appears it may be a compiler bug. Any possible workarounds?
Upvotes: 6
Views: 2392
Reputation: 393064
I reproduced the problem with VS2010. You need to call the example
function, though:
#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>();
}
This works:
#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>();
}
I have been looking for workarounds, but none working yet, I tried up to and including this nice permutation, but no luck yet:
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);
};
}
Tough one this...
Upvotes: 3
Reputation: 103713
The only error there is the missing semi-colon. Once that is fixed, it works fine.
#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>();
}
As this appears to be a bug in VC10's lambda implementation, a possible workaround is to create a local functor class:
template<typename T> void example()
{
struct Foo {
int operator()(byte * start) { return T::magic(start); }
};
std::function<int (byte*)> test = Foo();
}
Upvotes: 4
Reputation: 361472
I'm sure you're doing something wrong, because I'm able to call a static method using the syntax T::f()
inside the lambda:
#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;
}
Demo : http://ideone.com/IPakS
So please post more info. Till this is the answer. Try compare your code with this and see if you're doing something terribly wrong.
If you're using GCC, did you compile your code with -std=c++11
option?
Upvotes: 0