Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于概念的模板成员函数重载_C++_Templates_C++ Concepts_C++20 - Fatal编程技术网

C++ 基于概念的模板成员函数重载

C++ 基于概念的模板成员函数重载,c++,templates,c++-concepts,c++20,C++,Templates,C++ Concepts,C++20,在缺少概念的情况下如何重载模板类的模板成员函数的示例如所示 现在大致尝试使用概念编写类似的内容: template <typename T> struct Foo{ Foo(T elem): elem_(elem) {} template <typename U = T> requires Integral<U> int get() { return -1; } template <typenam

在缺少概念的情况下如何重载模板类的模板成员函数的示例如所示

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

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_;
};
模板
结构Foo{
Foo(T elem):elem_(elem){}
模板需要积分
int get(){
返回-1;
}
模板需要Bool
int get(){
返回0;
}
T元素;
};
有两种组织方式:
1.将声明和定义保持在一起:这是可以预期的
2.分离声明和定义:未能编译()

鉴于上述情况,我有两个问题:
1.由于SFINAE的原因,
模板成员\u fn…
最初是需要的。没有办法通过概念来避免这种情况,从而进一步简化代码吗?

2.如何正确区分声明和定义?

首先,声明和定义中的模板约束必须相同(请参阅)。否则,编译器无法推断定义引用了哪个声明

因此,此代码将编译:

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;
  }
模板
结构Foo{
Foo(T elem):elem_(elem){}
模板需要积分
int get();
模板需要Bool
int get();
T元素;
};
模板
模板需要积分
intfoo::get(){
返回-1;
}
模板
模板需要Bool
intfoo::get(){
返回0;
}
然后,不需要使用默认模板参数的概念检查延迟技巧,因为可以将约束关联到函数中的函数:

模板
结构Foo{
Foo(T elem):elem_(elem){}
int get()需要整数;
int get()需要Bool;
T元素;
};
模板
int Foo::get()需要整数{
返回-1;
}
模板
int Foo::get()需要Bool{
返回0;
}

如果保留声明(而不是删除声明),它将失败,因为调用了不明确的函数。请注意,编译器对C++20特性的支持仍然是实验性的。使用
Integral
来表示只使用
int
有点困难surprising@Barry只是想让它成为一个最小的运行示例。嗨,当尝试使用显式专门化(如wandbox示例)时,它会遇到一个类似ODR的错误:。我的猜测是,这是因为名称混乱中没有涉及概念,导致了这种双重定义-但是,我如何应用通常用于分隔模板的声明/impl的显式专门化?@tangy这是一个bug,后面的require子句属于函数的签名:。在这个答案中暴露的第一个技术应该工作。就像在GCC概念TS实现的bug中一样。@ Tyy既不符合概念TS也不符合C++ 20。我想改变C++名称的粗细对于实现C++概念的实现来说太重了。
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;
  }