the following code snippet worked in Visual Studio 2005 (with boost 1.34) but it fails to compile in Visual Studio 2015 (with boost 1.62) saying that "error C2672: 'boost::bind': no matching overloaded function found"
Am I missing something here?
Thank you!
typedef boost::shared_ptr< int > SProxySharedPtr;
SProxySharedPtr m_sptr_proxy;
auto a = boost::bind(&SProxySharedPtr::reset, &m_sptr_proxy);
boost::shared_ptr<.>::reset() is an overloaded member function. As a consequence, you have to designate explicitly which overload you want to use:
auto a = boost::bind(static_cast<void(SProxySharedPtr::*)()>(&SProxySharedPtr::reset), &m_sptr_proxy);
I tried to use GCC but saw similar errors. The only way I can get it compile is to subclass boost::shared_ptr as below (but maybe this is not what you are asking for):
typedef boost::shared_ptr<int> SProxySharedPtr;
struct Bar : SProxySharedPtr {
void reset() {
SProxySharedPtr::reset();
}
};
int main()
{
const Bar m_sptr_proxy;
boost::bind(&Bar::reset, &m_sptr_proxy);
}
Related
While trying to debug an issue with an assert macro I came across this problem. Using __declspec(noinline) on a lambda function in a template class generates a syntax warning in Visual Studio 2017:
error C2760: syntax error: unexpected token '__declspec', expected '{'
This is the failing code:
template<class R>
class test
{
public:
void DoStuff()
{
[]() __declspec(noinline) { }; // syntax error
}
};
int WinMain(void)
{
return 0;
}
If I go to my project settings and switch my platform toolset from v141 (vs2017) to v140 (vs2015) in the general section of the project properties dialog the error goes away .
If I change the class to not be a template class it also compiles correctly:
class test
{
public:
void DoStuff()
{
[]() __declspec(noinline) { }; // compiles fine
}
};
int WinMain(void)
{
return 0;
}
I'm curious why this wouldn't succeed using the v141 platform toolset. Is there some other project setting that could be affecting this?
I was able to fix this by updating Visual Studio 2017 to the latest version (15.9.7). Previously I was running version 15.6.7. Thanks to everyone who looked in and commented! :)
It works in VC++ 2019, so may just be a regression in 2017?
I have such code:
#include <functional>
struct Foo {
template<typename T>
static void f(int);
};
template<>
void Foo::f<int>(int) {}
int main()
{
std::function<void(int)> func;
//func = static_cast<void (*)(int)>(Foo::f<int>);/works
func = Foo::f<int>;//compilation failure
return 0;
}
VS 2012 and 2013 Preview give compile time error at line:
func = Foo::f<int>;//compilation failure
error C3867: Foo::f: in function call no argument list, use "&Foo::f" to create pointer to member
error C2440: =: can not convert "overloaded-function" into "std::function"
But gcc 4.8.1, clang 3.3 and Intel Compiler 13.1.3 compile
this code with options (-Wall -pedantic -std=c++11) without
any warnings and errors.
So is this compiler bug of C++ compiler of Visual Studio?
Yes, it is a bug, visual studio 2013 rc compiles this without a problem so it looks like they have fixed it.
template<class CharType>
struct MyString
{
MyString()
{}
MyString(CharType*)
{}
};
int main()
{
char* narrow_str = 0;
MyString<char>(narrow_str); // error C2040
}
My compiler is VC++ 2013 RC.
The simplest code cannot be compiled because of the error C2040.
error C2040: 'narrow_str' : 'MyString' differs in levels of
indirection from 'char *'
Why?
The problem is this is actually not being parsed as a constructor call but as a variable definition. The problem is you already defined a variable narrow_str. You may have already known this but you can easily fix this by giving it a name.
template<class CharType>
struct MyString
{
MyString()
{}
MyString(CharType*)
{}
};
int main()
{
char* narrow_str = 0;
MyString<char> ns(narrow_str); // error C2040
}
BTW this is also the source of the most vexing parse which occurs when this type of syntax is used in a function argument.
To be honest though I'm surprised that you got a different error because both g++ and clang gave me a clear error.
your syntax in creating a struct is wrong .
change
MyString<char>(narrow_str); // error C2040
to
MyString<char> myString(narrow_str);
will be ok.
I'm trying to update a old project that has been building with visual studio 2005 to uses visual studio 2012, and I'm getting an error that I cant solve.
The code that works fine under VS2005:
#include <iostream>
#include <string>
#include <sstream>
using std::cout;
using std::wcout;
using std::endl;
using std::wstring;
using std::string;
class Value
{
public:
Value(const wstring& value)
{
v = value;
}
Value(Value& other)
{
this->v = other.v;
}
template<typename T>
operator T() const
{
T reply;
std::wistringstream is;
is.str(v);
is >> reply;
return reply;
}
operator wstring() const
{
return v;
}
private:
wstring v;
};
int main()
{
Value v(L"Hello World");
wstring str = v;
wcout << str << endl;
Value int_val(L"1");
int i = int_val;
cout << i + 1 << endl;
return 0;
}
When I'm compiling this under VS2012 I get an error on the line "wstring str = v;", the error is:
error C2440: 'initializing' : cannot convert from 'Value' to 'std::basic_string<_Elem,_Traits,_Alloc>'
1> with
1> [
1> _Elem=wchar_t,
1> _Traits=std::char_traits<wchar_t>,
1> _Alloc=std::allocator<wchar_t>
1> ]
1> No constructor could take the source type, or constructor overload resolution was ambiguous
I can kinda fix it by changing the operator signature from 'operator wstring() const' to 'operator const wstring&() const'. But why does the original code not work, even though it works in VS2005.
I'm not getting an error on the line "int i = int_val;".
This also compiles and runs fine with GCC (g++) in cygwin (version 4.5.3).
Update
To really simulate my real problem there was some information left out in the sample code above. In between the Value class and the usage is a few other classes. One that look like this:
class Config
{
public:
virtual Value getValue(const string& key) const = 0;
Value operator()(const string& key)
{
return getValue(key);
}
};
And the usage
const wstring value2 = config("key");
That will give the error above when compiling but also IntelliSense will give other hints on whats wrong and it says: "More than one user-defined conversion from "Value" to "const std::wstring" applies:" and it points at both the regular constructor and the move constructor of basic_string. So it seem to have something to do with rvalues to do and I have been reading up on that, and understand the basics. But there is probably a lot I am missing.
I find that I can fix this problem by changing the usage to:
const wstring&& value = config("key");
Then it seem like the VS2012 compiler understand which constructor it should use then.
Questions:
* Are there a way to not use && in this example?
* What is really happening here?
I put up the sample code on GitHub:
https://github.com/Discordia/ImplicitTypeConversion
In simple (hopefully not simplified) terms, with C++11, you'll have to start thinking of references in terms of lvalue and rvalue. Basically, C++11 gives you the ability to handle operations on references differently depending on whether or not you are dealing with a "temporary" object. This gives you ability to do things like move data internal to your object rather than copy in different situations. The down side to this is the effect you are seeing, where old code is not specific enough about which you are dealing with. There's more to it than that, it's not really something that can be fully explained in a short SO answer, but previous answers gave some good places to start. I would rework your code to provide both rvalue and lvalue operators (which it sounds like you're already on your way to doing).
I'm still new to boost::bind, and now porting a program that was written 2 yrs ago in 2009, seeing the compile error below. Any idea to workaround would be appreciated.
Extracted cpp file:
class ClassA {
private:
cNamespace::Bounds bounds_msg_;
void boundsHandler(const PublisherPtr& p) {
p->publish(bounds_msg_);
}
void funcA() {
node_->advertise<cNamespace::Bounds>("bounds", 10,
boost::bind(&ClassA::boundsHandler, this, _1)); // <---- Line 445
}
};
Error upon CMake:
/home/userA/ClassA.cpp:445: instantiated from here
/usr/include/boost/bind/bind.hpp:313: error: no match for call to ‘(boost::_mfi::mf1<void, ClassA, const PublisherPtr&>) (ClassA*&, const ros::SingleSubscriberPublisher&)’
Environment: Ubuntu 10.10, g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
Might not be necessary but API reference of function advertise is here, or:
template<class M >
Publisher advertise (const std::string &topic,
uint32_t queue_size,
const SubscriberStatusCallback &connect_cb,
const SubscriberStatusCallback &disconnect_cb=SubscriberStatusCallback(),
const VoidConstPtr &tracked_object=VoidConstPtr(),
bool latch=false)
It looks like the function object that is produced by boost::bind is called with a different type than the function you bound.
i.e. it's called with const ros::SingleSubscriberPublisher& argument, instead of the expected const PublisherPtr& p.
Assuming SubscriberStatusCallback is a boost::function, you should make sure its argument matches the one you bound.