Ale*_*oni 2 c++ c++-concepts c++20
我正在对概念进行一些实验,并且我试图限制成员函数,只有在满足概念时才必须实例化这些函数:
template <typename T>
concept Fooable = requires(T o)
{
o.foo(uint());
};
template <typename T>
concept Barable = requires(T o)
{
o.bar(uint());
};
class Foo
{
public:
using FooType = int;
void foo(uint) {}
};
class Bar
{
public:
using BarType = double;
void bar(uint) {}
};
template <typename T>
class C
{
public:
void fun(typename T::FooType t) requires Fooable<T> {}
void fun(typename T::BarType t) requires Barable<T> {}
};
int main()
{
C<Foo> f;
}
Run Code Online (Sandbox Code Playgroud)
这段代码在 GCC 11.2 和 Clang 14 上都不能编译,说:
main.cpp: error: no type named 'BarType' in 'Foo'
main.cpp: error: no type named 'BarType' in 'Foo'
void fun(typename T::BarType t) requires Barable<T> {}
~~~~~~~~~~~~^~~~~~~
main.cpp: note: in instantiation of template class 'C<Foo>' requested here
C<Foo> f;
^
Run Code Online (Sandbox Code Playgroud)
但是,由于我声明了一个C带有类型的对象Foo,所以我希望成员函数funwithBarType不会被实例化。
这可能是 GCC 和 Clang 的 bug 吗?或者我做错了什么?有什么方法可以使用概念来实现这一点吗?
由于fun不是模板函数,因此始终会被实例化,并且如果没有名为 的类型别名,typename T::BarType则会产生硬错误。你可能想做TBarType
template <typename T>
class C
{
public:
template<Fooable U = T>
requires requires { typename U::FooType; }
void fun(typename U::FooType t);
template<Barable U = T>
requires requires { typename U::BarType; }
void fun(typename U::BarType t);
};
Run Code Online (Sandbox Code Playgroud)
鉴于 与BarType概念 相关Barable,更合适的方法是将您的概念重新定义为(我替换uint()为因为标准中0U没有所谓的类型)uint
template<typename T>
concept Fooable = requires(T o) {
o.foo(0U);
typename T::FooType;
};
template<typename T>
concept Barable = requires(T o) {
o.bar(0U);
typename T::BarType;
};
template <typename T>
class C {
public:
template<Fooable F = T>
void fun(typename F::FooType t);
template<Barable B = T>
void fun(typename B::BarType t);
};
Run Code Online (Sandbox Code Playgroud)
这要求满足的类型Barable必须有一个名为 的类型别名BarType。
| 归档时间: |
|
| 查看次数: |
145 次 |
| 最近记录: |