2015-01-31 3 views
2

Так я работал на классе функций, и по умолчанию, я могу это сделать, и это работает:Ограничение количества аргументов в функции VARIADIC

int main(){ 
    function f("x^2+1"); 
    cout<<f(3)<<endl; 

return 0; 
} 

«Предположим, собственно включает в себя и пространство имен»

В любом случае, я хотел бы иметь возможность передавать несколько переменных и даже указывать, каковы эти переменные;

function f("x^2+y^2",x,y); // it doesn't really matter if it's x, 'x', or "x" 
cout<<f(3,4)<<endl; // input 3 as x, and 4 as y 

Я довольно уверен, что я мог бы что-нибудь придумать для конструктора с использованием VARIADIC функций, и даже решить правильно, но будет ли способ заставить оператора() аргументы взять ровно 2 значения?

Я просто смотрел на вариационные функции, потому что они действительно первые вещи, которые я видел в C++, которые могут принимать несколько аргументов, поэтому, если лучше сделать это каким-то другим способом, я все для этого.

+0

Моя рекомендация - начать с более простого варианта использования вариативных шаблонов, чтобы узнать, как они обычно используются. Чтобы решить эту конкретную проблему, вам нужно будет выработать частичное применение аргументов к представлению функции (поскольку вариативные шаблоны являются рекурсивными), что не очень тривиально. – OmnipotentEntity

+0

Я бы предостерег от использования обычных вариабельных функций C для этого, потому что они не являются строго безопасными. (См. Уязвимости printf.) – OmnipotentEntity

ответ

2

Вы можете ограничить количество вариационных аргументов, используя static_assert.

template <typename ... Args> 
void operator()(Args&&... args) 
{ 
static_assert(sizeof...(Args) <= 2, "Can deal with at most 2 arguments!"); 
} 

Или вы могли бы использовать enable_if

template <typename ... Args> 
auto operator()(Args&&... args) -> std::enable_if_t<sizeof...(Args) <= 2> 
{ 
} 
+0

Я бы, скорее всего, использовал первый, но как именно он работает? Будет ли это возвращать компиляционную ошибку, если я передам три аргумента? В противном случае я могу просто сравнить sizeof ... (Args) с размером, переданным в конструктор. Кроме того, есть ли конкретная причина, по которой вы используете вариационный шаблон? Как насчет наличия (Args args && ...)? Все переменные, которые я буду вводить, будут в любом случае рассматриваться как удвоенные, так что есть точка для шаблона? – blackbeltJR

1
template<class T> 
using double_t=double; 
template<class...Ts> 
using nfun=std::function<double(double_t<Ts>...)>; 

template<class...C> 
nfun<C...> func(const char*,C...c); 

, который будет возвращать п-арной std::function, равное количеству аргументов 'переменная' в func.

Так func("x^2+y",'x','y','z') вернет std::function<double(double,double,double)> в качестве примера.

+0

вы, вероятно, имели в виду 'decltype (void (std :: declval ()), 0.) ...' –

+0

@piotrs. или просто полностью уничтожить decltype. – Yakk