2012-11-07 98 views
0

我有下面的代碼。我必須爲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){} 
}; 

反正我能避免對字符串以外類型的多個「返回false」語句?

+1

「hel」類型是「const char *」,而不是「string」。 – Gorpik

+0

'template bool operator()(U&other)const'適合我。這可能是因爲你正在使用'const char *'。 – Pubby

回答

1

問題是我在我的變種中使用了const char*。更改以下行:

MyVariant s1 = "hello world!"; 

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

解決了這個問題,並得到了模板版本工作。

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

它不起作用:「/usr/include/boost/variant/variant.hpp:832:32:錯誤:無效值不會被忽略,因爲它應該是」 – Meysam

+0

@Meysam對不起,請參閱我編輯的答案 – BigBoss

+0

感謝它的工作原理。但在這種情況下似乎沒有必要。 – Meysam

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

+0

你能否創建您在[http://ideone.com](http://ideone.com/)測試和工作的代碼的副本? – Meysam

+0

@Meysam看http://ideone.com/Ipt4cQ –

相關問題