【问题标题】:full specialization of template functions with std::if_enabled_t parameter带有 std::if_enabled_t 参数的模板函数的完全专业化
【发布时间】:2020-04-26 09:30:26
【问题描述】:

我正在尝试编写一个函数,该函数为所有非枚举类型实现一般行为,为所有枚举类型实现一般行为,然后能够通过完全专门化来专门化某些类型的特定行为功能。到目前为止,这是我的代码:

// Func.h

#include <cstdio>
#include <type_traits>

template <typename T, std::enable_if_t<!std::is_enum<T>{}>* = nullptr >
void Func()
{
    printf("General case\n");
}

template <typename T, std::enable_if_t<std::is_enum<T>{}>* = nullptr >
void Func()
{
    printf("enum\n");
}

template <>
void Func<bool>()
{
  printf("bool\n");
}


// main.cpp
#include <Func.h>

enum Enum
{
    A,
    B
};

int main()
{
  Func<float>();
  Func<Enum>();
  Func<bool>();
}

它无法编译,我真的不知道如何正确处理。如果我让专门的原型在上面的代码中,我得到这个链接错误:

error LNK2005: "void __cdecl Func<bool,0>(void)" (??$Func@_N$0A@@@YAXXZ) already defined in main.obj

如果我制作专用原型 template&lt;&gt; void Func&lt;bool, nullptr&gt;(),我会收到以下编译错误:

error C2912: explicit specialization 'void Func<bool,nullptr>(void)' is not a specialization of a function template

这些测试是使用带有 c++14 标准的 Visual Studio 2015 编译器完成的

我不知道从哪里开始,任何帮助将不胜感激

【问题讨论】:

  • Visual Studio 2015 编译器使用 C++14 标准。我编辑了问题以添加此信息

标签: c++ templates enums template-specialization


【解决方案1】:

您收到链接错误,因为Func&lt;bool&gt;() 是在包含在多个编译单元中的头文件中定义的。解决方法很简单:把inline放在void Func&lt;bool&gt;()之前:

template<>
inline void Func<bool>()
{
    // ...
}

函数模板隐含为inline,但函数和显式模板特化为are not。如果在头文件中定义,则应标记为inline

【讨论】:

  • 嗬,我注意到如果你在相应的 cpp 文件中移动函数的定义,它也可以工作。我不明白的是,为什么完全专用的模板函数在常规函数没有的标头中简单声明时会获得多个声明。
  • 每次包含“Func.h”时,编译器都会为Func&lt;bool&gt;() 生成代码。您获得的副本数量与包含此标头的编译单元的数量一样多。常规函数遵循完全相同的规则。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-24
  • 2021-12-11
  • 1970-01-01
  • 2018-06-06
  • 2023-03-28
  • 1970-01-01
相关资源
最近更新 更多