C字符串作为模板非类型参数可在gcc 6.3中使用,但不适用于Visual Studio 2017(x64为19.16.27027.1)

ole*_*leg 6 c++ templates visual-studio

如下代码:

#include <iostream>

template<const char* Pattern> void f() {
    std::cout << Pattern << "\n";
}

static constexpr const char hello[] = "Hello";

int main() {
    f<hello>(); //Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27027.1 for x64
    //  Copyright (C) Microsoft Corporation.  All rights reserved.
    //
    //  string-as-template-parameter.cpp
    //  string-as-template-parameter.cpp(10): fatal error C1001: An internal error has occurred in the compiler.
    //  (compiler file 'msc1.cpp', line 1518)
    //   To work around this problem, try simplifying or changing the program near the locations listed above.
    //  Please choose the Technical Support command on the Visual C++
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

由gcc(g ++(Debian 6.3.0-18 + deb9u1)6.3.0 20170516)编译时有效,但由VS 2017编译时结果为C1001。

作为解决方法,我使用:

#include <iostream>

template<const char** Pattern> void f() {
    std::cout << *Pattern << "\n";
}

static const char* hello = "Hello";

int main() {
    f<&hello>();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有没有人想提供更好的解决方案?可能是初始代码有一个错误被gcc跳过了吗?

P.W*_*P.W 5

有没有人想提供更好的解决方案?

您可以改用引用std::string

#include <iostream>
#include <string>

template<std::string & Pattern> void f() {
    std::cout << Pattern << "\n";
}

static std::string hello = "Hello";

int main() {
    f<hello>(); 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这可以在Visual Studio中使用MSVC进行编译。

之所以可行,是因为根据Cppreference,带有链接的命名左值引用被允许作为非类型参数。(请注意,这hello不是本地的。)