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;
}