【问题标题】:Can I overload template variables?我可以重载模板变量吗?
【发布时间】:2025-12-12 12:55:02
【问题描述】:

我想这样声明:

template <typename T>
constexpr enable_if_t<is_integral_v<T>, int[]> foo = { 1, 2 };

template <typename T>
constexpr enable_if_t<is_floating_point_v<T>, int[]> foo = { 10, 20, 30 };

但是当我尝试I'm getting this error:

错误:template&lt;class T&gt; constexpr std::enable_if_t&lt;std::is_floating_point&lt;_Tp&gt;::value, int []&gt; foo的重新声明
注意:之前的声明template&lt;class T&gt; constexpr std::enable_if_t&lt;std::is_integral&lt;_Tp&gt;::value, int []&gt; foo&lt;T&gt;

我觉得这应该是合法的,因为为任何给定的模板参数定义的foo 永远不会超过一个。我可以做些什么来帮助编译器理解这一点吗?

【问题讨论】:

  • @VTT 也许你能详细说明一下?你说这应该是可能的吗?如果有,怎么做?

标签: c++ templates overloading enable-if template-variables


【解决方案1】:

没有重载。

使用 enable if 的声明很好,但不能有多个,因为变量不可重载。

有了专业化,就像上课一样,它工作得很好:

#include <iostream>
#include <type_traits>

using namespace std;

template <typename T, typename = void>
constexpr int foo[] = {10, 20, 30};

template <typename T>
constexpr int foo<T, enable_if_t<is_integral_v<T>>>[] = { 1, 2 };


int main() {
    cout << foo<int>[0] << endl;
    cout << foo<float>[0] << endl;
}

由于它没有超载,单个std::enable_if 就足够了。 enable if 被认为比没有特化更特化,只要满足条件就会被采用,保留非整型模板参数的默认情况。

Live example

【讨论】:

  • @vahancho 是的,它确实可以编译。我添加了一个编译器资源管理器链接。如果您的实现不支持 CTAD,请报告错误
  • @Fureeish 好吧,那么值得一提的是它不能使用 MS 编译器进行编译。例如:godbolt.org/z/M53dq1 (-std=c++17 -O3)。我弄错了吗?
  • @vahancho msvc 有不同的命令行参数样式:godbolt.org/z/Xjai2A (/std:c++17 /O2)
  • @JonathanMee 我用 c 风格的数组语法替换了。方括号在模板角括号之后。
  • @JonathanMee:您缺少尖括号:Fixed。纪尧姆已经涵盖了方括号的错位。