基于概念的模板成员函数重载
Concept based Template member functions overloads
我们如何在没有概念的情况下重载模板 class 的模板成员函数的示例显示在 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 <typename T> template <typename U=T> member_fn...
原来是SFINAE需要的。有没有办法通过 Concepts 来进一步简化代码来避免这种情况?
2.如何正确分离声明和定义?
首先,模板的约束在声明和定义中必须相同(参见[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;
}
我们如何在没有概念的情况下重载模板 class 的模板成员函数的示例显示在 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 <typename T> template <typename U=T> member_fn...
原来是SFINAE需要的。有没有办法通过 Concepts 来进一步简化代码来避免这种情况?
2.如何正确分离声明和定义?
首先,模板的约束在声明和定义中必须相同(参见[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;
}