Создание концепции для функции шаблона элемента для использования с boost :: any в Stack Overflow

Я пытаюсь создать концепцию для использования с boost :: any. Эта концепция должна сказать, что
класс имеет функцию-член с сигнатурой void templateFunction (T t). Я получил это, чтобы скомпилировать и работать нормально, но только для одного типа за один раз. Разве то, что я пытаюсь сделать, невозможно?

#include <iostream>

#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/any_cast.hpp>
#include <boost/type_erasure/builtin.hpp>
#include <boost/type_erasure/operators.hpp>
#include <boost/type_erasure/member.hpp>
#include <boost/type_erasure/free.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/any.hpp>

using namespace std;
namespace mpl = boost::mpl;
using namespace boost::type_erasure;

class Foo
{
public:

template <class T>
void templateFunction(T t)
{
cout << t << endl;
}
};

template<class C, class T>
struct has_template_function
{
static void apply(C& cont, const T& arg) { cont.templateFunction(arg); }
};

namespace boost
{
namespace type_erasure
{
template<class C, class T, class Base>
struct concept_interface<has_template_function<C, T>, Base, C> : Base
{
void templateFunction(typename as_param<Base, const T&>::type arg)
{ call(has_template_function<C, T>(), *this, arg); }
};
}
}

int main()
{
any<has_template_function<_self, int>, _self&> c = Foo();
c.templateFunction(5);

//Compile error: cannot convert parameter 1 from 'const char [6]' to 'const int &'
//c.templateFunction("Hello");

return 0;
}

2

Решение

Это отчасти возможно из-за перегрузки и задокументировано в официальном Boost.TypeErasure документация.

Предостережение, как сказано в комментариях:

Вы не можете печатать шаблоны и сохранять их полиморфную природу

Следовательно, вам нужно будет явно указать перегрузки в требованиях для вашего boost :: typeerasure :: any type.

Вам нужно изменить свой концептуальный интерфейс, как описано в документации, и добавить перегрузку строки в раздел требований.

Ваш пример, модифицированный для обработки перегрузок:

#include <iostream>

#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/any_cast.hpp>
#include <boost/type_erasure/builtin.hpp>
#include <boost/type_erasure/operators.hpp>
#include <boost/type_erasure/member.hpp>
#include <boost/type_erasure/free.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/any.hpp>
#include <string>
#include <utility>

using namespace std;
namespace mpl = boost::mpl;
using namespace boost::type_erasure;

struct FooStruct
{
template <class T>
void templateFunction(T t)
{
cout << t << endl;
}
};

template<class T, class U>
struct has_template_function
{
static void apply(T& t, const U& u) { t.templateFunction(u); }
};

namespace boost {
namespace type_erasure {

template<class T, class U, class Base, class Enable>
struct concept_interface< ::has_template_function<T, U>, Base, T, Enable> : Base
{
typedef void _fun_defined;
void templateFunction(typename as_param<Base, const U&>::type arg)
{
call(::has_template_function<T, U>(), *this, arg);
}
};

template<class T, class U, class Base>
struct concept_interface< ::has_template_function<T, U>, Base, T, typename Base::_fun_defined> : Base
{
using Base::templateFunction;
void templateFunction(typename as_param<Base, const U&>::type arg)
{
call(::has_template_function<T, U>(), *this, arg);
}
};

}
}

ostream& operator<<(ostream& os, const std::pair<int, string>& pair) {
os << "(" << pair.first << ", " << pair.second << ")";
return os;
}

int main()
{
any<
mpl::vector
<
has_template_function<_self, int>,
has_template_function<_self, std::string>,
has_template_function<_self, std::pair<int,std::string>>
>
, _self&> c = FooStruct();

c.templateFunction(5);

c.templateFunction("Hello");

c.templateFunction(std::make_pair(5, "Hello"));

return 0;
}
2

Другие решения

Других решений пока нет …