Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > boost::bind и специализированный шаблон функции


Автор: Zerstroer 15.5.2013, 17:12
Доброго всем времени суток!

Проблема следующая:
Использую в одном из методов класса в своей программе boost::bind, который вызывает шаблонную функцию-член класса, имеющую специализацию для определенного типа (string). При использовании компилятора gcc-4.4 c ключиком -std=c++0x - код компилился, при переходе на gcc-4.7 (-std=c++11) код компилироваться перестал.
Прилагаю следующий код, который воспроизводит проблемы, с которыми я столкнулся:

Код

#include <cstdlib>
#include <boost/bind.hpp>
#include <string>
#include <iostream>
#include <vector>
#include <boost/operators.hpp>
#include <algorithm>

using namespace std;

class Cla{
    public:
        
    template <typename MyTy>  
    void tFunction(MyTy i){
        cout << "Общий случай шаблона"  << endl;
        cout << i << endl;
    }    
    
   //Вариант 1
   template<typename MyTy = string> void tFunction(string i){
        cout << "Специализированный шаблон"  << endl;
        cout << i.length() << endl;
    }
    
    //boost должен вызвать шаблонную член-функцию и её специализацию.
    void boostFunction(int i, string s){
        vector<int> intv = { i };
        vector<string> strv = { s };
     
        for_each(intv.begin(), intv.end(), boost::bind(&Cla::tFunction<int>, this, _1));
        for_each(strv.begin(), strv.end(), boost::bind(&Cla::tFunction<string>, this, _1));
               
    }
    
};

//Вариант 2 - выношу специализированную шаблонную член-функцию
//template<> void Cla::tFunction<string>(string i){
//    cout << "Специализированный шаблон"  << endl;
//    cout << i.length() << endl;
//}

int main(int argc, char** argv) {
    Cla c;
    string s = "Blabla";
    int i = 100;
    c.boostFunction(i, s);
    return 0;
}


Конкретно в данном случае компилятор выдает портянку, начинающуюся на
Код

 error: no matching function for call to ‘bind(<unresolved overloaded function type>, Cla* const, boost::arg<1>&)’


Я так понял, что это связано с тем, что bind воспринимает шаблоную и специализированную шаблонную функцию как перегруженные.
Я так же пробовал вынести определение специализированной шаблонной функции вне тела класса, но нарывался уже на другой косяк:
Код

error: specialization of ‘void Cla::tFunction(MyTy) [with MyTy = std::basic_string<char>]’ after instantiation

Я так понял, что это связано с попыткой использования в теле класса специализированной шаблонной функции, объявленной вне класса.

Подскажите, как методически правильнее всего решить эту проблему. 
Если что-то объяснил непонятно - задайте уточняющие вопросы.

Автор: Zerstroer 15.5.2013, 17:40
Прошу прощения, пример привел не совсем точный (в нем проблема решается на раз-два).
Этот пример точнее:

Код

#include <cstdlib>
#include <boost/bind.hpp>
#include <string>
#include <iostream>
#include <vector>
#include <boost/operators.hpp>
#include <algorithm>

using namespace std;

/*
 * 
 */
class Cla{
    public:
    Cla(int i, string s){
        vector<int> intv = { i };
        vector<string> strv = { s };     
        for_each(intv.begin(), intv.end(), boost::bind(&Cla::tFunction<int>, this, _1));
        for_each(strv.begin(), strv.end(), boost::bind(&Cla::tFunction<string>, this, _1));
    }

        
    template <typename MyTy>  
    void tFunction(MyTy i){
        cout << "Общий случай шаблона"  << endl;
        cout << i << endl;
    }    
    
   //Вариант 1
   //template<typename MyTy = string> void tFunction(string i){
   //     cout << "Специализированный шаблон"  << endl;
   //     cout << i.length() << endl;
   // }            
    
};

//Вариант 2
template<> void Cla::tFunction<string>(string i){
    cout << "Специализированный шаблон"  << endl;
    cout << i.length() << endl;
}




int main(int argc, char** argv) {    
    string s = "Blabla";
    int i = 100;
    Cla c(i, s);   

    return 0;
}


Добавлено через 13 минут и 7 секунд
Почему-то голова у меня включается после того как я уже написал пост и сижу в полной уверенности, что мне помогут.
Проблема оказалась тривиальна.
Проблема решена:

Код

#include <cstdlib>
#include <boost/bind.hpp>
#include <string>
#include <iostream>
#include <vector>
#include <boost/operators.hpp>
#include <algorithm>

using namespace std;


class Cla{
    public:
    Cla(int i, string s);
      
private:
    template <typename MyTy>  
    void tFunction(MyTy i){
        cout << "Общий случай шаблона"  << endl;
        cout << i << endl;
    }    
        
    void iFunction(int i){
        cout << "Не шаблонная функция" << endl;
        cout << i << endl;
    }        
};

template<> void Cla::tFunction<string>(string i){
    cout << "Специализированный шаблон"  << endl;
    cout << i.length() << endl;
}

Cla::Cla(int i, string s){
        vector<int> intv = { i };
        vector<string> strv = { s };
        for_each(intv.begin(), intv.end(), boost::bind(&Cla::iFunction, this, _1));
        for_each(intv.begin(), intv.end(), boost::bind(&Cla::tFunction<int>, this, _1));
        for_each(strv.begin(), strv.end(), boost::bind(&Cla::tFunction<string>, this, _1));
               
    }


int main(int argc, char** argv) {
    
    string s = "Blabla";
    int i = 100;
    Cla c(i, s);
    return 0;
}


Спасибо всем не успевшим откликнуться.
Прошу прощения за беспокойство.

Автор: VSB 19.5.2013, 10:24
Только зачем тебе boost, если теперь есть std::bind из <functional>

Автор: Zerstroer 19.5.2013, 12:38
В реальной задаче boost::bind я использовал по внутри функций boost::program_options, поэтому использование boost в контексте конкретно моей задаче обосновано.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)