【问题标题】:Concept based Template member functions overloads基于概念的模板成员函数重载
【发布时间】:2019-01-20 09:14:08
【问题描述】:

this snippet 中显示了我们如何在没有概念的情况下重载模板类的模板成员函数的示例。

现在大致尝试使用概念编写类似的东西:

template <typename T>
struct Foo{
    Foo(T elem): elem_(elem) {}
    template <typename U = T>  requires Integral<U>
    int get() {
        return -1;
    }
    template <typename U = T>  requires Bool<U>
    int get() {
        return 0;
    }
    T elem_;
};

有两种组织方式:
1. 将声明和定义放在一起:这按预期工作。 Code Snippet
2.声明和定义分离:编译失败(Code Snippet)

鉴于上述情况,我有两个问题:
1. 原来需要template &lt;typename T&gt; template &lt;typename U=T&gt; member_fn...的原因是因为SFINAE。有没有办法通过概念来避免这种情况以进一步简化代码?
2. 如何正确分离声明和定义?

【问题讨论】:

  • 如果您保留声明(而不是删除它们),它将因为调用不明确的函数而失败。请注意,编译器对 C++20 功能的支持仍处于试验阶段。
  • Integral&lt;T&gt; 表示只是 int 有点令人惊讶
  • @Barry 只是为了让它成为一个最小的运行示例。

标签: c++ templates c++-concepts c++20


【解决方案1】:

首先,模板的约束在声明和定义中必须相同(参见[temp.over.link]/6)。否则编译器无法推断出哪个声明引用了定义。

所以这段代码会编译:

template <typename T>
struct Foo{

  Foo(T elem): elem_(elem) {}

  template <typename U = T>  requires Integral<U>
  int get() ;

  template <typename U = T>  requires Bool<U>
  int get() ;

  T elem_;
  };

template<class T>
template<class U> requires Integral<U> 
int Foo<T>::get() {
  return -1;
  }
template<class T>
template<class U> requires Bool<U>
int Foo<T>::get()  {
  return 0;
  }

然后不需要使用默认模板参数的概念检查延迟技巧,因为可以将约束与trailing require-clause中的函数相关联:

template <typename T>
struct Foo{

  Foo(T elem): elem_(elem) {}


  int get() requires Integral<T>;

  int get() requires Bool<T>;

  T elem_;
  };

template<class T>
int Foo<T>::get() requires Integral<T> {
  return -1;
  }

template<class T>
int Foo<T>::get() requires Bool<T> {
  return 0;
  }

【讨论】:

  • 嗨,当尝试这个和明确的专业化(如 wandbox 示例)时 - 它会遇到类似 ODR 的错误:coliru.stacked-crooked.com/a/0f527e6119ba8684。我的猜测是这是因为概念不涉及导致这种双重定义的名称修改 - 但是我如何应用通常用于分离模板的声明/实现的显式专业化?
  • @tangy 这是一个 bug,后面的 require 子句属于函数的签名:timsong-cpp.github.io/cppwp/intro.defs#defns.signature.member。此答案中公开的第一种技术应该可以工作。
  • 就像 gcc 概念 TS 实现的错误一样?
  • @tangy 既不符合概念 TS 也不符合 C++ 20。我想更改 C++ 名称修饰对于旨在试验 C++ 概念的实现来说太繁重了。
猜你喜欢
  • 2018-12-28
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
  • 2021-09-16
  • 2013-09-22
  • 1970-01-01
  • 2019-11-23
  • 1970-01-01
相关资源
最近更新 更多