Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C string as template non-type parameter works in gcc 6.3 but does not work in Visual Studio 2017 (19.16.27027.1 for x64)

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?

like image 262
oleg Avatar asked Apr 02 '19 10:04

oleg


People also ask

Can we use non-type parameters as arguments template?

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 allowed for non-type template?

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.

What is a non-type?

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".


1 Answers

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.)

like image 116
P.W Avatar answered Sep 19 '22 08:09

P.W