2016-06-19 2 views
1

Допустим, у меня есть на структуруC++ Предоставление произвольного параметра для шаблона с шаблоном для проверки?

struct FStruct 
{ 
    FName ObjectName; 
}; 

И у меня есть шаблонный статическую функцию

template <typename T, typename LookType> 
static T* GetFromArray(LookType LookFor, TArray<T> InArray) 
{ 
    for (T* TIter : InArray) 
    { 
     if (LookFor == TIter.LookParameter) // <-- How to provide LookParameter? 
     { 
      return TIter; 
     } 
    } 

    return nullptr; 
} 

Мне нужно предоставить ему переменную из этого ObjClass, чтобы проверить против, как я могу это сделать?

По существу, использование может быть что-то вроде:

MyStaticLib::GetFromArray<FStruct, FName>(FName("Bob"), PeopleArray, FStruct::ObjectName) 
+0

Я не вижу, как это может работать. Если 'Titer' является' T * ', то я не вижу, как' Titer.somethingorother' будет действительным C++. –

+2

Предлагаю вам взглянуть на стандартную функцию ['std :: find'] (http://en.cppreference.com/w/cpp/algorithm/find). Прежде всего, не пытайтесь изобретать колесо, но если вы это сделаете, посмотрите, как одна перегрузка обрабатывает все возможные сопоставимые типы сравнения с использованием предиката * * (что-то вызываемое, как указатель на функцию, или объект с функцией 'operator()' member (которая включает [лямбда-выражения] (http://en.cppreference.com/w/cpp/language/lambda))). –

+0

@SamVarshavchik Был обеспокоен тем, что может быть так, есть ли альтернативный способ по существу сделать выше? Предположим, что нет .. Я мог бы перегружать функции в качестве последнего средства для разных типов параметров. – Vii

ответ

1

К сожалению, это не представляется возможным передать имя поля в порядке, вы предлагаете, это попахивает рефлексии, C++ не имеет. То, что вы можете сделать довольно легко в современном C++, это передать функцию, которая кодирует имя поля как часть его логики. Это в конечном итоге сводится к предложению Йоахима Пилеборга в комментариях. А именно, вы можете написать:

auto found = std::find_if(InArray.begin(), InArray.end(), 
    [&] (const auto& x) { 
     return x.LookParameter == LookFor; 
}); 

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

Существует не чистый путь, который должен написать макрос:

#define GET_FROM_ARRAY(array, fieldname, lookfor) \ 
    std::find_if(array .begin(), array .end(), \ 
    [&] (const auto& x) { \ 
     return x. fieldname == lookfor ; \ 
    }) 

auto found = GET_FROM_ARRAY(InArray, FName, LookFor); 

Как программист C++, я одновременно обязан обеспечить этот ответ, как это технически говоря, ближе всего к тому, что вы хотите , и я также обязан сказать вам, что это плохая идея. Таков C++.

+0

Спасибо за помощь, кажется, каждый раз, когда кто-то предлагает макрос, он приходит с отказом от ответственности «не делай этого» :). – Vii

+0

@Vii Это потому, что большинство хороших программистов на С ++ теперь стоят дорого. Этот макрос не может быть помещен в пространство имен, вы не можете создавать другие абстракции поверх макроса, потому что препроцессор работает первым, приводит к неожиданным ошибкам, например, дважды оцениваются аргументы и т. Д. Для перспективы я почти наверняка не допустил бы макрос Я написал выше, чтобы пройти обзор кода в любой команде, в которой я был вовлечен, но, эй, я просто передаю вам веревку, вы можете решить, хотите ли вы повесить себя или нет ;-) –

Смежные вопросы