是否可以使用模板来识别两种不同的类型?

时间:2012-11-07 09:02:06

标签: c++ templates boost

我有以下代码。我必须为operator()中可用的所有类型定义MyVariant(bool,int,string,const char *)。但是,由于StartsWith仅适用于类型字符串,因此所有其他仿函数都应返回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;
}

上面的代码工作正常。但为了使其更简洁,我认为可以使用模板为字符串设置一个仿函数,为其他类型设置一个仿函数。我尝试了以下方法,但结果是第二个仿函数始终是调用的。

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){}
};

以下代码也不起作用:

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){}
};

无论如何,我可以为字符串以外的类型避免多个“return false”语句吗?

3 个答案:

答案 0 :(得分:2)

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;}

答案 1 :(得分:1)

这个适用于我:

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){}
};

偏离主题:std::string::compare()返回int

答案 2 :(得分:1)

问题在于我在我的变体中使用const char*。更改以下行:

MyVariant s1 = "hello world!";

MyVariant s1 = string("hello world!");

解决了问题并使模板版本正常工作。