Неуказанные значения константных выражений и ODR - PullRequest
7 голосов
/ 19 апреля 2020

Рассмотрим эту программу в трех файлах:

// a.h

#include<iostream>

constexpr auto f() {
    int i = 0;
    auto l1 = [](int& j) { return ++j; };
    auto l2 = [](int& j) { return j*=2; };
    return l1(i) + l2(i);
}

template<auto V> struct constant {};

inline auto g() {
    constexpr auto x = f();
    std::ios_base::Init init; // Avoid possible initialization order issues
    std::cout << x;
    return constant<x>{};
}

static auto x = g();
inline auto y = g();
// a.cpp

#include "a.h"
// main.cpp

#include "a.h"

int main() {
}

с a.cpp и main.cpp, скомпилированными как единицы перевода. Я думаю, что определение g должно быть нарушением ODR, потому что f() может иметь значение 1 или 3, тем самым изменяя тип возвращаемого значения g() и то, что он будет выводить на std::cout.

Однако все имена в определении после поиска имен и разрешения перегрузки ссылаются на одни и те же объекты в каждой единице перевода, которая включает a.h, поэтому я не вижу, какое из требований ODR нарушается.

Не нарушает ли программа правило одного определения. Если да, то какая именно часть нарушена?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...