嵌套模板 (C++17) 编译在 VS19 上失败

问题描述

代码

(注意模板没有被实例化——这不是错误,即使没有它编译也会失败) main.cpp:

namespace mylib {
    template<typename ...Params>
    class SomeClass {
        public:
            template<typename ...nestedParams>
            class nestedClass {
            };

            template<typename ...nestedParams>
            nestedClass<nestedParams...> createnestedInstance();
    };
}

template<typename... Params>
template<typename... nestedParams>
typename mylib::SomeClass<Params...>::template nestedClass<nestedParams...>
mylib::SomeClass<Params...>::createnestedInstance() {
    return SomeClass::nestedClass<nestedParams...>();
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.17)
project(msvc_exploit001)

set(CMAKE_CXX_STANDARD 17)

add_library(msvc_exploit001 main.cpp)

GCC (Msys64 MinGW64): 编译没有警告

Visual Studio 社区 2019:

msvc_exploit001.cpp(25): error C2244: 'mylib::SomeClass<Params...>::createnestedInstance': unable to match function deFinition to an existing declaration
msvc_exploit001.cpp(25): note: see declaration of 'mylib::SomeClass<Params...>::createnestedInstance'
msvc_exploit001.cpp(25): note: deFinition
msvc_exploit001.cpp(25): note: 'mylib::SomeClass<Params...>::nestedClass<nestedParams...> mylib::SomeClass<Params...>::createnestedInstance(void)'
msvc_exploit001.cpp(25): note: existing declarations
msvc_exploit001.cpp(25): note: 'mylib::SomeClass<Params...>::nestedClass<nestedParams...> mylib::SomeClass<Params...>::createnestedInstance(void)'
NMAKE : Fatal error U1077: 'C:\PROGRA~2\MICROS~4\2019\COMMUN~1\VC\Tools\MSVC\1427~1.291\bin\Hostx64\x64\cl.exe' : return code '0x2'
Stop.
NMAKE : Fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\bin\HostX64\x64\nmake.exe"' : return code '0x2'
Stop.
NMAKE : Fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\bin\HostX64\x64\nmake.exe"' : return code '0x2'
Stop.
NMAKE : Fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\bin\HostX64\x64\nmake.exe"' : return code '0x2'
Stop.

由 MSVC 打印错误包含声明和定义的相同签名,但它坚持认为它们不匹配。

我正在 Windows 10 上编译,使用 CMake (CLion) 和认编译器选项(仅指定 C++17 标准级别)

解决方法

似乎 msvc 的 template 有问题。这样编译

namespace mylib {
    template<typename ...Params>
    class SomeClass {
        public:
            template<typename ...NestedParams>
            class NestedClass {
            };

            template<typename ...NestedParams>
            NestedClass<NestedParams...> createNestedInstance();
    };
}

template<typename... Params>
template<typename... NestedParams>
typename mylib::SomeClass<Params...>::NestedClass<NestedParams...>
mylib::SomeClass<Params...>::createNestedInstance() {
    return SomeClass::NestedClass<NestedParams...>();
}

int main() {
    auto sc = mylib::SomeClass<int,bool>();
    auto c = sc.createNestedInstance<float,double>();
}

如评论中所述,标准可能需要该模板。在这种情况下,也许您应该向 Microsoft 提交错误报告。