Enforce exact invokable signature in C++

  c++, c++20, templates

i have a function that takes an invokable, and i want to make sure that the signature of the passed invokable is exactly the specified one.

#include <type_traits>
#include <cassert>
#include <iostream>

template<typename F>
requires std::is_invocable_v<F, float&>
float fn(F&& f) {
    float v;
    return v;

int main() {
    float v = 17.0;
    std::cout << "v=" << v << std::endl;   // returns v=17

    float v2 = fn([&v](float& b){
        b = v; 
    std::cout << "v2=" << v2 << std::endl; // returns v2=17

    float v3 = fn([&v](float b){
        b = v;
    std::cout << "v3=" << v3 << std::endl; // returns some random value (uninitialized)

    return 0;


Here v3 is left uninitialized because the lambda takes the argument by value instead of a reference.

My question is now, how can i make sure that an invokable passed to fn always takes by reference, co my code works.

Thank you.

Source: Windows Questions C++