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

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.

Related

Creating an array of string_view elements throws error: unable to find string literal operator ‘operator""sv’ with

I have the following (modified) code where I want to create an array of string_view type objects.
I see this error when compiling corresponding to each line
unable to find string literal operator ‘operator""sv’ with ‘const char [8]’, ‘long unsigned int’ arguments
"Sensor2"sv,
The code:
#include <iostream>
#include <array>
#include <string_view>
struct Abc
{
static constexpr std::array<std::string_view, 6> SomeValues = {
"Sensor1"sv,
"Sensor2"sv,
"Actuator1"sv,
"Actuator2"sv,
"Cpu1"sv,
"Cpu2"sv
};
};
int main()
{
Abc abc;
std::cout<<abc.SomeValues[3];
return 0;
}
You need using namespace std::literals;.
See also this question.

VS 2015 Error when using nested lambda

Here is a toned down version of my use case which compiles fine on gcc 4.9.3 and clang 3.7 but fails on VS 2015 Update 2.
#include <functional>
#include <string>
#include<memory>
namespace A {
using handle = std::function<void(std::string)>;
void func(std::string, handle) {
}
}
class B : public std::enable_shared_from_this<B> {
public:
void func();
};
void B::func()
{
auto && cast = std::static_pointer_cast<B>(shared_from_this());
auto const another_variable = [cast]() -> void
{
A::func("hello", [&cast](std::string){ } );
};
}
int main() {
return 0;
}
Here are the errors that I get
Error(s):
source_file.cpp(23): error C2440: '<function-style-cast>': cannot convert from 'const std::shared_ptr<_Ty>' to 'B::func::<lambda_4a58826445f3685613b078cf10fc9f7e>::()::<lambda_8290a9c207487c2dc2e26a5b929b4850>'
with
[
_Ty=B
]
source_file.cpp(23): note: No constructor could take the source type, or constructor overload resolution was ambiguous
source_file.cpp(23): error C2660: 'A::func': function does not take 1 arguments
Interestingly, it compiles fine on VS 2013 as well. Am I missing something very obvious?

no viable conversion from 'string *' (aka 'basic_string<char> *') to 'shared_ptr<string>

So I have this code:
#include <iostream>
#include <list>
#include <string>
#include <memory>
using namespace std;
int main() {
{
shared_ptr<string> str = new string("Marius");
cout << str + " MMG";
}
return 0;
}
By compiling it with:
clang++ -Wall -g -std=c++14 test.c++ -o test
I get:
test.c++:11:22: error: no viable conversion from 'string *' (aka 'basic_string<char> *') to 'shared_ptr<string>'
shared_ptr<string> str = new string("Marius");
Where is the mistake?
With GCC I get the same error.
The constructor for std::shared_ptr that takes a raw pointer is explicit.
Also note there is no operator= that takes a raw pointer, so the following would also fail to compile:
std::shared_ptr<std::string> ptr;
ptr = new std::string{"Marius"};
To construct one properly, there are two options:
std::shared_ptr<std::string> ptr{new std::string{"Marius"}};
// or the (much) preferred
auto ptr = std::make_shared<std::string>("Marius");

Getting pointer to boost::any::operator=

I want to get pointer to boost::any::operator=, so i did this:
bool(__thiscall boost::any::*func)(const bool&) = &(boost::any::operator=<bool>);
but now, compiler says
initializing' : cannot convert from 'overloaded-function' to 'bool (__thiscall boost::any::* )(const bool &)'
None of the functions with this name in scope match the target type
i also tried to make it this way:
bool(__thiscall boost::any::*func)(const bool&) = static_cast<(boost::any::*)(const bool&)>(&(boost::any::operator=<bool>));
but there is compiler says: "syntax error : '('" in this line
can anybody helps me, please?
P.S. I make instaces of boost::any in the code above
You can not specify the arguments in the assignment of the member function pointer.
This will do it:
#include <iostream>
#include <boost/any.hpp>
int main() {
boost::any any = false;
std::cout << boost::any_cast<bool>(any) << std::endl;
typedef boost::any& (boost::any::*assign_operator)(const bool&);
assign_operator assign = &boost::any::operator =;
(any.*assign)(true);
std::cout << boost::any_cast<bool>(any) << std::endl;
return 0;
}

auto keyword is not deducing type of string

I've this simple code:
#include <string>
#include <iostream>
using namespace std;
int main() {
string s1 = "rohit";
auto len = s1.size();
cout << len;
}
When I compile this code on Ubuntu 12.04, it shows following error:
test.cc: In function ‘int main()’:
test.cc:8:10: error: ‘len’ does not name a type
auto len = s1.size();
^
test.cc:10:13: error: ‘len’ was not declared in this scope
cout << len;
^
I've got g++ 4.8.1. Is there some changes with the usage of auto keyword in g++ 4.8.1?
The error: ‘len’ does not name a type leads me to believe that you didn't compile in C++11 mode and that it's using the old, C++98 meaning of the keyword auto.