当前位置: 首页 > 知识库问答 >
问题:

d::enable_if选择一个专业

轩辕煌
2023-03-14

我正在努力理解std::enable_if以及在static_assert/常规模板专门化中使用它的好处。

读了一圈后我发现:

当不满足特定条件时,这对于在编译时隐藏签名非常有用,因为在这种情况下,不会定义成员enable_if::类型,尝试使用它编译应该会失败。http://www.cplusplus.com/reference/type_traits/enable_if/

我的问题是:为什么编译器指责我说C类已经声明了?,当一次只能使用一个声明时。

class Interface{};

class Foo : public Interface{};

template <class T, typename = typename std::enable_if<std::is_base_of<Interface,T>::value>::type>
class C{
   // Some custom implementation
}

template <class T, typename = typename std::enable_if<!std::is_base_of<Interface,T>::value>::type>
class C { 
  //Some fallback / default implementation
}

int main() {
    C<Foo> myVariable;
}

导栓中的相同行为:https://godbolt.org/z/cbfhG9q54

提前感谢!


共有1个答案

江奕
2023-03-14

您不能像重载函数模板那样重载类模板,但可以部分地对它们进行专门化(这是函数模板无法做到的):

#include <ios>
#include <iostream>
#include <type_traits>

class Interface
{};
class Foo : public Interface
{};

template <class T, typename = void>
struct C
{
    // Some default impl.
    static constexpr bool is_default_impl{true};
};

template <class T>
struct C<T, std::enable_if_t<std::is_base_of_v<Interface, T>>>
{
    // Some custom implementation.
    static constexpr bool is_default_impl{false};
};

int main()
{
    std::cout << std::boolalpha 
        << C<int>::is_default_impl << " "  // true
        << C<Foo>::is_default_impl;        // false
}

注意,本示例要求变量模板std::is_base_of_v使用C17,这是一个简写常量std::is_base_oftrait的value成员,别名模板std::enable_if_t使用C14,它为std::enable_iftrait的type成员别名声明添加别名。

 类似资料:
  • 您的源码发布 需要 一个许可证。在美国,如果没有指定许可证,用户就没有合法的权利下载、修改或分发。此外,除非你告诉他们要遵循什么规则,否则人们不能对你的代码做出贡献。选择一个许可证是很复杂的,所以这里有一些建议: 开源许可。 这里有许多可以选择 开源许可   。 通常, 这些许可分为两类: 一类是让使用者能自由地使用软件 (像这种更加开发的开源许可有 MIT , BSD & Apache) 。 另

  • 头文件: "boost/utility/enable_if.hpp" 有时候,我们希望控制某个函数或类模板的特化是否可以加入到重载决议时使用的重载或特化的集合中。例如,考虑一个重载的函数,它有一个版本是带一个int参数的普通函数,另一个版本是一个函数模板,它要求参数类型 T 具有一个名为type的嵌套类型。它们看起来可能象这样: void some_func(int i) { std::cou

  • 问题内容: 我有一个像这样的程序: 我想从一个选择内调用此过程,如下所示: 但是我知道这是很痛苦的错误。有人可以指出我正确的方向吗?我将需要访问过程的所有列,以便在最终“选择”中(加入?)。该过程中的SQL代码很痛苦,因此首先要这样做! 问题答案: Ticket_FiscalTotals过程返回一个包含一些字段的数据集,但是您只需要其中一个- 。将您的过程重写为存储的函数- 。 另一种方法是在过程

  • 当选择为项目应用一个许可证时,如果可能,请尽量选择一个而不是建一个新的。选择已有的许可证有两个原因: 熟悉度。如果你使用最流行的三,四个许可证之一,人们会感到在使用代码前不需要阅读这些法律条款,因为他们之前已经阅读过了。 质量。除非你有一个可以支配的律师团队,否则你很难得到一个法律坚实的许可证。这里说的许可证时大量思想和经验的产品;除非你的项目确实有不同寻常的需要,你不太可能做的更好。 关于应用这

  • 我有两个表和 names表有以下列表: -男性姓名从nameID 1到nameID 10 -女性姓名从nameID 11到nameID 21 -两者都从nameID 23到nameID 31 性别表有三个属性: -女性 -男性 -两者 我正在使用引导选择选项,我想显示从nameID11到nameid21的名称,如果用户从gender选择选项中选择女性,等等,这是可能的吗?我看到其他帖子,我注意到他

  • 问题内容: 我得到了一个看起来像这样的select元素,现在我想将其打开并选择值为t3的选项,因此我尝试了如下操作: 现在,这将打开菜单,但没有选择选项标签,我想到了使用select()而不是click(),但还不支持select(),或者至少是我尝试使用该方法时收到的消息。我运行以下扩展PHPUnit_Extensions_Selenium2TestCase。 问题答案: 这是相对简单的。 这应