Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda as a template variable

During some investigation related to "Variable template" I found out some strange code behaviour for me. Does standard say anything about this behaviour?

//Header.h
#pragma once

template<typename T>
auto myvar = []() -> T&{
    static T v;
    return v;
};

//Source.cpp
#include <iostream>
#include "Header.h"

void testFunction()
{
    std::cout << myvar<int>() << '\n';
}

//main.cpp
#include <iostream>
#include "Header.h"

void testFunction();

int main(int argc, char **argv) 
{
    myvar<int>() = 10;

    testFunction();

    std::cout << myvar<int>() << '\n';
}

Output:

0
10

I expect:

10
10
like image 266
Igor Avatar asked Oct 03 '18 14:10

Igor


People also ask

How to use lambda expression as a template parameter?

The following solution should work, as lambda expression merely creates an anonymous struct, which should be appropriate as a template parameter. However, a lot of errors are spawned. Code example: struct A {int x; int y;}; std::set <A, [](const A lhs, const A &rhs) ->bool { return lhs.x < rhs.x; } > SetOfA;

What variables can be used in a lambda expression?

Variable defined by the enclosing scope of a lambda expression are accessible within the lambda expression. For example, a lambda expression can use an instance or static variable defined by its enclosing class.

What is a custom lambda function?

A custom LAMBDA function does not require VBA or macros. In computer programming, the term LAMBDA refers to an anonymous function or expression. An anonymous function is a function defined without a name. In Excel, the LAMBDA function is first used to create a generic (unnamed) formula.

How to use the template angle brackets in a lambda function?

@tartaruga_casco_mole The lambda is a function object. To use the template angle brackets you need a type (or a constexpr template). I assume that per the specification the compiler will have to treat the < in your example as a less than operator on the lambda object which will obviously fail.


1 Answers

Currently, you have ODR violation:

In both translation units, you have (after substitution)

auto myvar<int> = []() -> int&{
    static int v;
    return v;
};

but lambda declares a different type for each TU, so you have lambda1 and lambda2 for myvar<int>.

Each lambda has its own static, that is why you see that result in practice (but program is ill-formed anyway, NDR).

like image 102
Jarod42 Avatar answered Sep 21 '22 21:09

Jarod42