PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, November 4, 2022

[FIXED] Why cant we declare std::function with auto

 November 04, 2022     c++, c++20, lambda     No comments   

Issue

I got following code:

 template<typename T>
concept con1 = requires(T t, std::string s){
    { t[s] } -> std::same_as<std::string>;
};

using function_signature = std::function<void ( con1 auto  functor)>; // ERROR!

while the compiler has no problem me defining the lambda directly:

auto lambda_1 = [](con1 auto functor){....} 

The reason why I want the former to work is the following:

 template<std::semiregular T>
 class R{

     T functor;
     R() = default;
     register_functor(T functor_) { functor = std::move(functor_);}
  }

If I get to instantiate my class using the signature like:

  auto rr = R<function_signature>(); 

I can get to register my functor at a later stage, and even change the function at run time as long as I keep the signature the same. Using the lambda directly means I am stuck with whatever my lambda is at the time I instantiate the class R


Solution

auto in a lambda parameter list doesn't represent one single automatically-inferred type like it would in a variable initialization, it represents that the lambda has a templated operator() which has a whole parameterized family of function signatures.

You can't instantiate a template that expects a concrete type (and std::function does) with a parameterized family of types. You could create a parameterized family of typedefs, each formed by instantiating std::function:

template<con1 T> using function_signature = std::function<void (T)>;

But this doesn't get you any closer to being able to write R<function_signature>. For that, you'd need template<template class T<U>> class R; and then R needs to somehow provide the type parameter T2 in T<T2> functor.

In the end, it comes down to std::function being a wrapper to a pointer-to-member function (among other flavors), and a pointer-to-member function cannot point to a whole template family of member functions.

This also fails:

auto lambda_1 = [](con1 auto functor){....};
auto pmf = &lambda_1::operator(); // cannot take address of template member function

Put another way, type-erasure doesn't work on templates. Instantiating the template requires its type.



Answered By - Ben Voigt
Answer Checked By - Gilberto Lyons (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing