我正在对概念进行一些实验,并且我试图拥有约束成员函数,只有在满足概念时才必须实例化这些函数:
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;
}
这段代码无法在 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;
^
但是,由于我声明的是 Foo
类型的 C
对象,因此我希望成员函数 fun
具有 BarType
不会被实例化。
这可能是 GCC 和 Clang 的错误吗?或者我做错了什么?有什么方法可以使用概念来实现这一点吗?
最佳答案
由于 fun
不是模板函数,因此 typename T::BarType
始终会被实例化,并且如果 T
没有名为 BarType
的类型别名。你可能想做
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);
};
鉴于 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);
};
这要求满足 Barable
的类型必须具有名为 BarType
的类型别名。
关于c++ - 具有依赖参数类型的概念约束成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73097441/