【问题标题】:Lambda as a template variableLambda 作为模板变量
【发布时间】:2018-10-03 14:35:17
【问题描述】:

在一些与“变量模板”相关的调查中,我发现了一些奇怪的代码行为。标准是否说明了这种行为?

//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';
}

输出:

0
10

我希望:

10
10

【问题讨论】:

  • 您有两个不同的模板实例化,每个实例化一个 translation unit。该函数的每个实例都有自己的静态局部变量。这很好,符合预期。
  • @Someprogrammerdude:我想说违反 ODR,所以没有有效的期望。
  • 我不确定你要在这里证明什么,但我不能说我喜欢这段代码。
  • @Someprogrammerdude 不是隐式内联的变量模板实例化吗?
  • @Quentin 没有说on cppreference.com,但它可能在规范中。

标签: c++ templates language-lawyer


【解决方案1】:

目前,您违反了 ODR:

在两个翻译单元中,您都有(替换后)

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

但是 lambda 为每个 TU 声明了不同的类型, 所以你有lambda1 和lambda2 对应myvar&lt;int&gt;。

每个 lambda 都有自己的 static,这就是您在实践中看到该结果的原因(但程序无论如何都是不正确的,NDR)。

【讨论】:

  • 看起来是真的。我没有看到任何其他解释。 (但如果我声明任何其他类型,例如“int”,它会按我的预期工作。注意:在 Vandevoorde 的最后一本书“C++ 模板:完整指南”中,他说不同翻译单元中的每个“模板变量”实例都有内联行为和价值是共享的)。似乎这种行为只与 lambdas 有关。 Tnx
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-20
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多