代码之家  ›  专栏  ›  技术社区  ›  The Dreams Wind

占位符是否允许作为函数模板返回类型?

  •  1
  • The Dreams Wind  · 技术社区  · 2 年前

    考虑以下模板及其专业化:

    template<typename R>
    R func() {
        return 0;
    }
    
    template<>
    auto func() {
        std::cout << "Auto deduced" << std::endl;
        return 1;
    }
    

    我不确定是否允许这样的声明,但当使用Xcode编译它时,clang会发出一个奇怪的错误:

    clang: error: unable to execute command: Segmentation fault: 11
    clang: error: clang frontend command failed due to signal (use -v to see invocation)
    Apple clang version 14.0.0 (clang-1400.0.29.202)
    Target: x86_64-apple-macos12.3
    Thread model: posix
    

    尽管不能调用专业化, MSVC compiles it just fine .是否允许这样的专业化?如果允许,如何使用?

    1 回复  |  直到 2 年前
        1
  •  5
  •   The Dreams Wind    2 年前

    [dcl.spec.auto.general]/13 提供了以下详细信息:

    使用占位符类型的已声明返回类型的函数或函数模板的重新声明或专门化也应使用该占位符,而不是推导类型。类似地,具有声明的返回类型但不使用占位符类型的函数或函数模板的重新声明或专门化不应使用占位符。

    换句话说,任何不使用占位符返回类型的函数模板(即使是模板参数)都不能专门使用占位符返回型:

    template<typename R>
    R func() { return 0; }
    
    template<>
    int func() { return 1; } // OK
    
    template<>
    auto func() { return "str"; } // Error. Redeclaration
    

    类似地,任何使用占位符返回类型的模板都只能专用于占位符返回类型:

    template<typename R>
    auto func(R arg) { return arg; }
    
    template<>
    auto func(int arg) { return arg; } // OK
    
    template<>
    float func(float arg) { return arg; } // Error. Redeclaration
    

    对于clang来说,这是一个编译器错误,MSVC接受它是错误的,而且只是 GCC rejects it as expected :

    <source>:9:6: error: template-id 'func<>' for 'auto func()' does not match any template declaration
        9 | auto func() {
          |      ^~~~
    <source>:4:3: note: candidate is: 'template<class R> R func()'
        4 | R func() {
          |   ^~~~
    Compiler returned: 1