c++ - 具有依赖参数类型的概念约束成员函数

标签 c++ c++20 c++-concepts

我正在对概念进行一些实验,并且我试图拥有约束成员函数,只有在满足概念时才必须实例化这些函数:

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/

相关文章:

c++ - 如何使 Clang 静态分析器从命令行输出其工作?

c++ - 错误 c2036 : unknown size if structure

c++ - 使用 C++ 概念检查其他类型的函数是否存在

c++ - 在 C++20 中仍然无法转发所有可调用对象吗?

c++ - 使用 Codelite IDE 和 Ubuntu 执行格式错误

c++ - C++17/C++2a 编译时的哈希类型

c++ - 具有编译时间常量的模板化 Lambda 函数

c++ - 如何decltype模板方法C++?

c++ - 将非算术类型作为参数传递给 cmath 函数是否有效?