Decltype (function) as a class member

I have:

int foo(int x) { return x+1; } struct Bar { decltype(foo) operator(); }; int main() { Bar bar; printf("%d\n",bar(6)); } 

which leads to a slightly starting compiler error message (g ++ 4.6.1):

 error: declaration of 'operator()' as non-function 

When changing the name of the participant to

  decltype(foo) blubb; 

and using this result results in a linker error:

 undefined reference to `Bar::blubb(int)' 

Is this the expected behavior?

+6
source share
3 answers

It seems that you want to “copy” the signature of another function in order to create a function with the same signature. Since decltype(foo) indeed a type of function (and not a pointer to that function, which would be decltype(&foo) and lead to a pointer declaration), you can use it to declare a function with the same signature as another function.

As indicated by the linker error:

 undefined reference to `Bar::blubb(int)' 

this will work great with your compiler. However, it seems that gcc has not yet fully implemented this part of the standard, since it will not accept the syntax for the same using the function call operator. Klang by the way. happy to accept it, and then the connection with the errors

 undefined reference to `Bar::operator()(int)' 

Your question about why this linker error exists indicates a misunderstanding of what decltype really does.

He will simply appreciate the type, not more. The blubb definition is blubb no way associated with the foo definition. It can be clearer when writing how

 typedef decltype(foo) x; x blubb; 

Now you can, as an alternative to typedef x, explicitly indicate the type of function that will in no way change what blubb is. You still need to define it. And since there is no syntax to define it using the decltype method, you obviously need to write it as

 int Bar::operator()(int) { ... } 

which, most likely, and, unfortunately, will lead to a defeat of the purpose / advantage of using decltype for the declaration, since it will not allow you to automatically "copy" the signature.

+5
source

This is a wild assumption based on watching you use printf:

 printf("%d\n",bar(6)); 

This allows me to suggest that you really need a function return type, not a function type. If so, then you are using decltype incorrectly. You get the return type of the function by "mimicking" the use of the function, i.e.

 decltype(foo(0)) operator() (int); 

should be right for you. Otherwise, if this was not your attention, you skate on thin ice, setting the type of the function (and not the return type of the function) to the %d specifier.

Typically, decltype : decltype(@) gives the static type of the @ expression.

+2
source

That should work. I just used it here to capture any gobbledygook std::bind that was going to give me:

 class RiceFadingModel::Impl { public: Impl(double K, double A) : //... _M_re{system_now()}, _M_rd{_M_nu, _M_sigma}, _M_gen{std::bind(_M_rd, _M_re)} { } private: //... std::default_random_engine _M_re; /// The underlying Rice distribution. __gnu_cxx::__rice_distribution<double> _M_rd; /// The variate generator built from the pseudo-random number engine and the Rice distribution. decltype(std::bind(_M_rd, _M_re)) _M_gen; }; 

This works like a charm on gcc-4.7. Now that I think about it, I built it on mingw with gcc-4.5 too.

0
source

Source: https://habr.com/ru/post/908696/


All Articles