代码之家  ›  专栏  ›  技术社区  ›  Mohit

使用概念的部分专业化

  •  0
  • Mohit  · 技术社区  · 5 年前

    我刚才在读C++ 20概念的例子。现在我试图创建一个函数,如果给定的类型是哈希表或不使用混合了部分专门化的概念,则该函数将打印出来。但不幸的是它不起作用。

    #include <iostream>
    #include <string>
    
    template<typename T>
    concept Hashtable = requires(T a) {
        { std::hash<T>{}(a) } -> std::size_t;
    };
    
    struct Foo {};
    
    template <typename T>
    void Bar() {
        std::cout << "Type T is not a hashtable" << std::endl;
    }
    
    template <Hashtable T>
    void Bar<T> {
        std::cout << "Type T is a hashtable" << std::endl;
    }
    
    int main()
    {
        Bar<Foo>();
        Bar<std::string>();
    }
    

    我正在使用编译器版本GCC HEAD 9.0.1,编译器标志是 g++ prog.cc -Wall -Wextra -I/opt/wandbox/boost-1.69.0/gcc-head/include -std=gnu++2a "-fconcepts" . 它给出了以下编译器错误:

    prog.cc:18:6: error: template-id 'Bar<T>' used as a declarator
       18 | void Bar<T> {
          |      ^~~~~~
    prog.cc:18:6: error: variable or field 'Bar' declared void
    prog.cc:19:54: error: expected '}' before ';' token
       19 |     std::cout << "Type T is a hashtable" << std::endl;
          |                                                      ^
    prog.cc:18:13: note: to match this '{'
       18 | void Bar<T> {
          |             ^
    prog.cc:20:1: error: expected declaration before '}' token
       20 | }
          | ^
    

    Live Demo

    但我的期望是:

    Type T is not a hashtable
    Type T is a hashtable
    

    我的问题

    有可能专门使用概念吗?

    0 回复  |  直到 5 年前
        1
  •  3
  •   Barry    5 年前

    函数模板不能部分专用化(也永远不能)。概念不会改变这个规则。

    但是,函数模板 可以 超载(而且总是可能超载)。和概念 使之更容易:

    template <typename T>
    void Bar() {
        std::cout << "Type T is not a hashtable" << std::endl;
    }
    
    template <Hashtable T>
    void Bar() {
        std::cout << "Type T is a hashtable" << std::endl;
    }
    
    int main()
    {
        Bar<Foo>();           // calls the first Bar
        Bar<std::string>();   // calls the second Bar
    }
    

    我们说第二个 Bar 约束性更强 比第一个 酒吧 .

        2
  •  2
  •   Mohit    5 年前

    我已经用structs专门化替换了函数模板专门化,我的代码运行良好。请看下面的代码。

    // This file is a "Hello, world!" in C++ language by GCC for wandbox.
    #include <iostream>
    #include <string>
    
    template<typename T>
    concept Hashtable = requires(T a) {
        { std::hash<T>{}(a) } -> std::size_t;
    };
    
    struct Foo {};
    
    template <typename T>
    struct Boo {
        static constexpr char value[] = "Type T is not a hashtable";
    };
    
    template <Hashtable HashT>
    struct Boo<HashT> {
        static constexpr char value[] = "Type T is a hashtable";
    };
    
    template <typename T>
    void Bar() {
        std::cout << Boo<T>::value << std::endl;
    }
    
    int main()
    {
        Bar<int>();
        Bar<Foo>();
    }
    
        3
  •  1
  •   P.W    5 年前

    有可能专门使用概念吗?

    不,不可能部分地专门化概念。根据上的在线参考 Constraints and concepts :

    显式实例化,显式专门化, 或者不允许对概念进行部分专门化 (约束的原始定义的含义不能更改)。

    就函数模板而言,它们只能重载,不能部分专用。