使用带有部分特化的 std::enable_if<> 与类型有什么区别?

问题描述

在我一直从事的特定项目上工作时,模板编程的下一个级别(除了非常简单的使用之外)已经困扰了我好几个月。我尝试了很多方法,从 StackOverflow 剪切和粘贴,以及尝试理解和滚动我自己的方法,没有任何突破。我尝试过的一些技术在 SFINAE 上遇到了 std::enable_if<> 的障碍,所以我将问题提炼出来并询问了这个问题。

让我们从基线模板开始:

template<typename T>
struct foo
{
    string bar(const T& val);
};

然后将其特化为整数向量:

template<>
struct foo<vector<int> >
{
    string bar(vector<int> c);
};

正如预期的那样,这会编译并利用类型中的正确模板。但我需要能够更好地控制使用哪些模板。

我可以从 C++ reference 和许多其他站点中理解的最好的,如果我将 std::enable_if<> 添加到组合中(使用 enable_if_t<> 别名),以下应该给我完全相同的行为,替换std::enable_if_t<true,vector<int> > 仅包含 vector<int>

template<>
struct foo<std::enable_if_t<true,vector<int> > >
{
    string bar(vector<int> c);
};

它可以正常工作,按预期编译和运行。

但是,如果我改为使用部分专业化,事情就会有所不同。如果没有 std::enable_if<>,这也能正常工作:

template<typename T>
struct foo<vector<T> >
{
    string bar(vector<T> c);
};

添加 std::enable_if<true,vector<T> > 失败。我希望它替换为 vector<T>,它在上面工作:

template<typename T>
struct foo<std::enable_if_t<true,vector<T> > >
{
    string bar(vector<T> c);
};

但这给了我一个编译时错误

test.cpp:48:8: error: template parameters not deducible in partial specialization:
  463 | struct foo<std::enable_if_t<true,vector<T> > >
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:48:8: note:         ‘T’

我知道这是部分专业化。但是,之前的版本也是如此,没有 std::enable_if<>。显然,有一些不同的东西,但调试模板非常不透明,而且谷歌搜索也没有给我带来任何线索。所以我不清楚有什么不同,或者如何让编译器像没有 std::enable_if<> 一样处理这个问题。

请注意,最终目标是用其他容器中的模板类型替换 vector,我需要将顺序容器和关联容器分成​​不同的实现。我真的尝试了很多组合,包括可变参数和模板模板参数。我可以让他们中的许多人为多个容器工作,但每个人都有各种各样的问题,因为我想我正在得到答案。像这样的条件编译(显然基于 type_traits 启用/禁用)似乎可能有助于在不止一种情况下达成完整的解决方案。

在线版本在这里(只需交换第 47 和 48 行的注释):http://coliru.stacked-crooked.com/a/d4892db81a4c9957

任何帮助表示赞赏。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)