简体   繁体   中英

std::function of a value templated method compiles with clang and g++ but not with msvc

The following code compiles with clang v5.0.0 and g++ v8.1.0 but fails with visual studio (2013 and 2017):

#include <string>
#include <functional>
#include <iostream>

template <const char* name>
std::string fct() {
   return name;
}

const char toto[] = "toto";
std::function<std::string()> fctptr = fct<toto>;

int main(){
   std::cout << fctptr() << std::endl;
} 

The error is the following:

main.cpp(11): error C2440: 'initializing' : cannot convert from 'std::string (__cdecl *)(void)' to 'std::function<std::string (void)>'
1>          No constructor could take the source type, or constructor overload resolution was ambiguous

I tried to replace the std::function with a typedef to a function pointer, as such:

typedef std::string(*Fctptr)();
Fctptr fctptr = fct<toto>;

However, I got the same error.

Is it a bug with msvc compiler, or is the above code not standard compliant.

FWIW, the following failed to compile using g++ 6.4.0 ( g++ -std=c++11 ).

#include <string>
#include <functional>
#include <iostream>

template <const char* name>
std::string fct() {
   return name;
}

const char toto[] = "toto";
std::function<std::string()> fctptr = fct<toto>;

int main(){
   std::cout << fctptr() << std::endl;
} 

Here's the error message:

socc.cc:11:43: error: the value of ‘toto’ is not usable in a constant expression
 std::function<std::string()> fctptr = fct<toto>;
                                           ^~~~
socc.cc:10:12: note: ‘toto’ was not declared ‘constexpr’
 const char toto[] = "toto";

Changing the definition of toto to

constexpr char toto[] = "toto";

resolved the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM