Reputation: 18137
I've got the following code. I have to define the operator()
for all types available in MyVariant
(bool, int, string, const char*). However, since StartsWith
is only applicable to type string, all other functors should return false.
#include "boost/variant/variant.hpp"
#include "boost/variant/apply_visitor.hpp"
using namespace std;
using namespace boost;
typedef variant<bool, int, string, const char*> MyVariant;
class StartsWith
: public boost::static_visitor<bool>
{
public:
string mPrefix;
bool operator()(string &other) const
{
return other.compare(0, mPrefix.length(), mPrefix);
}
bool operator()(int &other) const
{
return false;
}
bool operator()(bool &other) const
{
return false;
}
bool operator()(const char* other) const
{
return false;
}
StartsWith(string const& prefix):mPrefix(prefix){}
};
int main(int argc, char **argv)
{
MyVariant s1 = "hello world!";
if(apply_visitor(StartsWith("hel"), s1))
{
cout << "starts with" << endl;
}
return 0;
}
The above code works fine. But in order to make it more concise, I thought it might be possible to use templates to have one functor for string, and one for other types. I tried the following, but the result is that the second functor is always the one invoked.
template<typename T>
class StartsWith
: public boost::static_visitor<bool>
{
public:
T mPrefix;
bool operator()(T &other) const
{
return other.compare(0, mPrefix.length(), mPrefix);
}
template<typename U>
bool operator()(U &other)const
{
return false;
}
StartsWith(T const& prefix):mPrefix(prefix){}
};
The following code did not work either:
class StartsWith
: public boost::static_visitor<bool>
{
public:
string mPrefix;
bool operator()(string &other) const
{
return other.compare(0, mPrefix.length(), mPrefix);
}
template<typename U>
bool operator()(U &other)const
{
return false;
}
StartsWith(string const& prefix):mPrefix(prefix){}
};
Is there anyway I can avoid multiple "return false" statements for types other than string?
Upvotes: 0
Views: 188
Reputation: 18137
The problem was that I was using const char*
in my variant. Changing the following line:
MyVariant s1 = "hello world!";
to
MyVariant s1 = string("hello world!");
solved the problem and got the template version working.
Upvotes: 1
Reputation: 74028
This one works for me:
class StartsWith
: public boost::static_visitor<bool>
{
public:
string mPrefix;
bool operator()(const string &other) const
{
return other.compare(0, mPrefix.length(), mPrefix);
}
template<typename U>
bool operator()(U other)const
{
return false;
}
StartsWith(string const& prefix):mPrefix(prefix){}
};
Off topic: std::string::compare() returns int
.
Upvotes: 1
Reputation: 6914
bool operator()(std::string const& other ) const {...}
template< class T >
typename boost::disable_if<boost::is_same<T, std::string>, bool >::type
operator()( T const& ) const {return false;}
Upvotes: 2