Программирование на C ++ - отложенные вызовы функций - PullRequest
4 голосов
/ 19 августа 2011

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

template <typename T> struct Task1
{
    T Arg1;
    Delegate<T> TaskDelegate;
};

У меня проблема в следующем:

Task1<const Foo&> MyTask;

Это приведет к тому, что параметр будет сохранен как постоянная ссылка. Кто-нибудь знает хорошее решение, чтобы обойти это? Я мог бы применять такие правила, как подпись делегата, всегда принимающая const & params, но это кажется ограничительным. Я всегда мог иметь две структуры задач (одну для ссылки и одну для значения), но это кажется неприятным.

Другим решением было бы создать следующее:

template <typename T1, typename T2> struct Task1
{
    T2 Arg1;
    Delegate<T1> TaskDelegate;
};

Есть ли в любом случае по умолчанию T2 того же типа, что и T1? Таким образом, всякий раз, когда у меня есть подпись значения метода, мне не нужны дополнительные параметры шаблона.

EDIT: Шаблон используется для многопоточного планировщика задач. Вот пример:

void MyClass::Populate(const std::string& instrText);

CTaskScheduler::Schedule(Task1<const std::string&>(this, &MyClass::Popluate, "MyString"));

Ответы [ 4 ]

8 голосов
/ 19 августа 2011

Вы можете взглянуть на реализацию function<> как в надстройке, так и в готовящемся стандарте.На самом деле, вы можете просто использовать function<>.Я думаю, что было решение (до C ++ 0x) всегда сохранять копию аргументов, если пользователь хочет ссылочная семантика , он может использовать ссылочную оболочку .

Что касается того, как получить значение, вы можете взглянуть на простую метафункцию для удаления const или &:

// Remove reference:
template <typename T>
struct remove_reference {
   typedef T type;
};
template <typename T>
struct remove_reference<T&> {
   typedef T type;
};

Аналогично для const.

2 голосов
/ 19 августа 2011

В дополнение к boost :: type_traits есть библиотека boos :: call_traits , специально созданная для решения подобных проблем. Также предусмотрены механизмы, позволяющие избежать проблемы с ссылками.

2 голосов
/ 19 августа 2011

Вы можете использовать библиотеку boost.type_traits , чтобы удалить постоянство параметра, используя boost::remove_const.

1 голос
/ 19 августа 2011

boost :: remove_const должен помочь вам в этом случае:

template <typename T> struct Task1
{
    typename boost::remove_const<T>::type Arg1;
    Delegate<T> TaskDelegate;
};

В качестве альтернативы, вы можете избежать использования boost, если используете специализацию шаблона для типов констант:

template <typename T> struct Task1
{
    T Arg1;
    Delegate<T> TaskDelegate;
};

template <typename T> struct Task1<const T>
{
    T Arg1;
    Delegate<const T> TaskDelegate;
};

(Предупреждение: не проверено)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...