The following code:
#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;
}
works when compiled by gcc (g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516) but results in C1001 when compiled by VS 2017.
As a workaround I use:
#include <iostream>
template<const char** Pattern> void f() {
std::cout << *Pattern << "\n";
}
static const char* hello = "Hello";
int main() {
f<&hello>();
return 0;
}
Does anybody have idea of more beautiful solution? May be initial code has an error which is skipped by gcc?
Non-type template arguments are normally used to initialize a class or to specify the sizes of class members. For non-type integral arguments, the instance argument matches the corresponding template parameter as long as the instance argument has a value and sign appropriate to the parameter type.
Which parameter is legal for non-type template? Explanation: The following are legal for non-type template parameters:integral or enumeration type, Pointer to object or pointer to function, Reference to object or reference to function, Pointer to member.
NoneType is the type for the None object, which is an object that indicates no value. None is the return value of functions that "don't return anything".
Does anybody have idea of more beautiful solution?
You can use a reference to std::string
instead.
#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;
}
This compiles with MSVC in Visual Studio.
This works because as per Cppreference, a named lvalue reference with linkage is allowed as a non-type parameter. (Note that hello
is not local.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With