【问题标题】:Is it possible to use templates to identify two different types?是否可以使用模板来识别两种不同的类型?
【发布时间】:2012-11-07 09:02:05
【问题描述】:

我有以下代码。我必须为MyVariant 中可用的所有类型(bool、int、string、const char*)定义operator()。但是,由于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”语句?

【问题讨论】:

  • “hel”类型是const char*,而不是string
  • template&lt;typename U&gt; bool operator()(U &amp;other)const 为我工作。这可能是因为您使用的是const char*

标签: c++ templates boost


【解决方案1】:
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;}

【讨论】:

  • 它不起作用:“/usr/include/boost/variant/variant.hpp:832:32: 错误: void 值没有被忽略”
  • 你是对的,这对你的情况来说是不必要的,但我想展示你如何根据类型启用或禁用函数,并避免使用相同语法的多个函数,但正如你所说,这是过度的你的情况
【解决方案2】:

这个对我有用:

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

【讨论】:

  • 能否请您创建一个您在http://ideone.com 测试和工作的代码的副本?
【解决方案3】:

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

MyVariant s1 = "hello world!";

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-18
    • 1970-01-01
    • 2016-01-24
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多