GCC'nin uyumlu olmadığını düşünüyorum. N3092 §5.1.2/5 der
bir lambda ekspresyonu için kapalı tip olan paramtereleri ve dönüş tip tarafından tarif edilen bir genel hat içi işlev çağrısı operatörü (13.5.4) sahip olmasıdır lambda-expression'ın parametre-bildirimi-ve sırasıyla geri dönüş-türü. Bu işlev çağrısı işleci, bildirilen const (9.3.1) ise ve yalnızca lambda ifadesinin parametresi bildirim-cümlesi değilse ve bunu değiştirilemiyorsa. kapatma nesnenin türü hakkında pek çok şey uygulama tanımlı ise
Yani, fonksiyon kendisi public
olmak için üye olmalı ve const
olmak statik olmayan üye olmalıdır.
DÜZENLEME: Bu program, operator()
'un, GCC 4.6'daki bir üye işlevi olduğunu belirtir; bu, 4.5 ile aynıdır.
#include <iostream>
#include <typeinfo>
using namespace std;
template< class ... > struct print_types {};
template<> struct print_types<> {
friend ostream &operator<< (ostream &lhs, print_types const &rhs) {
return lhs;
}
};
template< class H, class ... T > struct print_types<H, T...> {
friend ostream &operator<< (ostream &lhs, print_types const &rhs) {
lhs << typeid(H).name() << " " << print_types<T...>();
return lhs;
}
};
template< class T >
struct spectfun {
friend ostream &operator<< (ostream &lhs, spectfun const &rhs) {
lhs << "unknown";
return lhs;
}
};
template< class R, class ... A >
struct spectfun< R (*)(A ...) > {
friend ostream &operator<< (ostream &lhs, spectfun const &rhs) {
lhs << "returns " << print_types<R>()
<< " takes " << print_types<A ...>();
return lhs;
}
};
template< class C, class R, class ... A >
struct spectfun< R (C::*)(A ...) > {
friend ostream &operator<< (ostream &lhs, spectfun const &rhs) {
lhs << "member of " << print_types<C>() << ", " << spectfun<R (*)(A...)>();
return lhs;
}
};
template< class T >
struct getcall {
typedef decltype(&T::operator()) type;
};
int main() {
int counter = 0;
auto count = [=](int) mutable { return ++ counter; };
cerr << spectfun< getcall<decltype(count)>::type >() << endl;
}
çıkışı:
member of Z4mainEUlvE_, returns i takes i
DÜZENLEME: Tek sorun belli kapatma çağrısı operatörlerine işaretçileri ptmf şablon kalıplarını maç için başarısız olmasıdır gibi görünüyor. Çözüm, lambda mutable
ifadesini bildirmektir. Yakalama olmadığında ve sadece (sorunun giderilmesinin dışında) arama operatörünün yapısını değiştirirse, bu anlamsızdır.
template< class T >
struct getcall {
typedef decltype(&T::operator()) type;
static type const value;
};
template< class T >
typename getcall<T>::type const getcall<T>::value = &T::operator();
int main() {
auto id = [](int x) mutable { return x; };
int (*idp)(int) = id;
typedef decltype(id) idt;
int (idt::*idptmf)(int) /* const */ = getcall< decltype(id) >::value;
cerr << spectfun< decltype(idp) >() << endl;
cerr << spectfun< decltype(idptmf) >() << endl;
cerr << spectfun< getcall<decltype(id)>::type >() << endl;
çıkışı: değişken olmadan ve const ile
returns i takes i
member of Z4mainEUliE0_ , returns i takes i
member of Z4mainEUliE0_ , returns i takes i
, spectfun
son iki sorguları biri için imzalar yazdırmaz.
Bu, ücretsiz işlevler kullandığından g ++ uyumlu değil miydi? – GManNickG
Evet, bana yanlış anlatan GCC gibi geliyor. – jalf
@Gman, jalf: Bah, seçici işitme. GCC'nin yöntemi daha fazla arkadaşlık gerektirir… ha! – Potatoswatter