Я пытаюсь решить, при каких обстоятельствах следующий код может вызвать нарушение правила одного определения.
header.h
#pragma once
#include <cstddef>
template<typename T, typename U>
class C {
friend std::size_t f() {
// Uses the template parameter that doesn't change
return sizeof(T);
}
friend std::size_t g() {
// Uses the template parameter that does change
return sizeof(U);
}
friend std::size_t h() {
// Does not refer to template parameters
return 0;
}
};
// Declarations to help name lookup
std::size_t f();
std::size_t g();
std::size_t h();
src1. cpp
#include "header.h"
// Cause definintion of f(), g() and h()
template class C<int, double>;
src2. cpp
#include "header.h"
// Cause definintion of f(), g() and h()
template class C<int, float>;
Я явно создал две разные версии шаблон класса C
в двух разных единицах перевода. Если я свяжу единицы перевода вместе, у меня будут нарушения ODR?
Кажется очевидным, что будет нарушение ODR для g()
, потому что в каждой единице перевода его реализация различна.
А как же f()
и h()
? Реализация (то есть поток токенов) каждого из них останется неизменной между единицами перевода. Но оба они неявно используют разные экземпляры C
. Это имеет значение? Здесь нет поиска имени?