一个TU中的模板专门化被另一个TU隐藏

Template specialisation in one TU hidden by another TU

本文关键字:TU 另一个 隐藏 专门化 一个      更新时间:2023-10-16

我有一个类模板,它可以特殊化,以便更改用户定义类型的实用程序函数的行为。

我有一个翻译单元,它使用实用函数,我的类型的专门化可用。使用专门化。

在一个单独的翻译单元中,如果我调用效用函数而不包括专门化,它会改变另一个TU的行为(专门化不在两个 TU 中使用)

下面是一个完整的例子来描述我的问题:

check.h:定义了类模板,该类模板可以专门用于用户定义的类型

#pragma once
#include <iostream>
template<typename T>
struct Check
{
    static void type();
};
template<typename T>
void Check<T>::type()
{
    std::cout << "check fall-backn";
}
template<typename T>
void check(T&&)
{
    Check<T>::type();
}

type.h:我的用户定义类型

#pragma once
enum Foo
{
    FOO,
    BAR
};

type_check.h: 专门为Foo Check

#pragma once
#include "type.h"
#include "check.h"
template<>
struct Check<Foo>
{
    static void type()
    {
        std::cout << "check Foon";
    }
};

lib.h: 你头文件

#pragma once
void lib();

lib.cpp:TU源文件-使用type_check.h

的专门化
#include "lib.h"
#include "type_check.h"
void lib()
{
    check(FOO);
}

main.cpp:

#include "check.h"
#include "type.h"
#include "lib.h"
#include "type_check.h" // uncomment this to make specialisation avail to all
int main()
{
    check(5);
    lib();
//  check(FOO); // uncomment this to change behaviour of lib()`
    return 0;
}

结果:

main中调用lib()而不调用check(FOO)会导致以下结果:

check fall-back
check Foo

main中调用lib()check(FOO)的结果如下:

check fall-back
check fall-back <-- main changes behaviour of lib
check fall-back

main.cpp中包含type_check.h,然后在main中调用lib()check(FOO),结果如下:

check fall-back
check Foo
check Foo

问题:

Check<Foo>专门化不可用时,为什么在单独的TU中调用check(FOO)将其从lib.cpp的过载集中移除?

指出:

我不能只是把Check<Foo>专门化在同一个文件作为Foo的定义,因为Foo实际上是一个生成的文件(protobuf)

这违反了一个定义规则。链接器会看到同一个函数的两个函数定义,并从中选择一个。不需要诊断。

在这种情况下,void Check<Foo>::type通过lib.cpp中使用的check.h模板定义的实例化来定义一次,而另一个定义来自main.cpp中使用的type_check.h。

相关文章: