2016-04-18 6 views
-1

Я пытаюсь создать класс с членом std::function и operator(), который вызовет упомянутый член. Вот то, что я пробовал:Как инкапсулировать std :: function

template <class R, class... Args> 
class Func{ 
    public: 
    Func(std::function<R(Args...)> fnx) : fn(fnx) {} //Error 
    R operator()(Args... a) { return fn(a...); }  //Error 
    private: 
    std::function<R(Args...)> fn;     //Error 
}; 

Однако я получаю ошибку таинственное

error: function returning a function

в строках указывается как Error, что я не понимаю --- я не вижу возвращаемая функция. Где это, и как я могу это исправить?

Полный не-рабочий пример: http://coliru.stacked-crooked.com/a/603a84184d9666a8

#include <iostream> 
#include <functional> 

int foo(int a, int b) { return a+b; }  

template <class R, class... Args> 
class Func{ 
    public: 
    Func(std::function<R(Args...)> fnx) : fn(fnx) {} 
    R operator()(Args... a) { return fn(a...); } 
    private: 
    std::function<R(Args...)> fn; 
}; 

Func<int(int,int)> foox; 

int main() { 
    std::cout << foox(2,4); 
    return 0; 
} 
+1

Пожалуйста, смотрите: http://stackoverflow.com/help/mcve – cubuspl42

+0

я включить MCVE, сделал я не? – CygnusX1

+0

Ну, не совсем. Код самого класса отлично, и это был только код, включенный в вопрос. Мне нужно было перейти на внешний сайт, чтобы обнаружить ошибку. Насколько я понимаю, ссылки на внешние сайты должны быть только дополнением, но минимальный рабочий пример должен быть частью самого вопроса. Теперь его вид исправлен (я не уверен, что код нужно дублировать, хотя). – cubuspl42

ответ

0

Я думаю, вы хотите что-то вроде этого:

template<typename F> 
class Func; 

template<typename R, typename... Args> 
class Func<R(Args...)> { 
    // ... 
}; 

В противном случае, вы злоупотребляете Func так, как вы определили его.
Другими словами, здесь ваш пример кода один раз исправлено:

#include<functional> 
#include<iostream> 

int foo(int a, int b) { return a+b; } 

template<typename F> 
class Func; 

template<typename R, typename... Args> 
class Func<R(Args...)> { 
public: 
    Func(std::function<R(Args...)> fnx) : fn(fnx) {} 
    R operator()(Args... a) { return fn(a...); } 
private: 
    std::function<R(Args...)> fn; 
}; 

Func<int(int,int)> foox{foo}; 

int main() { 
    std::cout << foox(2,4); 
    return 0; 
} 
+0

Вы абсолютно правы, этого я и хотел достичь. Я думал, что «Func » - это то, что работает само по себе, и его не нужно объявлять как специализацию общего «F». – CygnusX1

+0

Downvoters, почему? – skypjack

+0

Сам вопрос также опускается вниз. Хотя проблема может быть базовой, я действительно не понимаю, почему она проголосовала как таковая. – CygnusX1

2

В этой строке ...

Func<int(int,int)> foox

... вы передаете int(int,int) в R, в то время как Args... пуст. Ошибка более очевидна в Clang:

a.cpp:9:24: error: function cannot return function type 'int (int, int)' 
    Func(std::function<R(Args...)> fnx) : fn(fnx) {} 
        ^
a.cpp:15:20: note: in instantiation of template class 'Func<int (int, int)>' requested here 
Func<int(int,int)> foox; 
       ^
a.cpp:10:5: error: function cannot return function type 'int (int, int)' 
    R operator()(Args... a) { return fn(a...); } 
    ^
a.cpp:12:19: error: function cannot return function type 'int (int, int)' 
    std::function<R(Args...)> fn; 
       ^

правильный способ объявить foox бы Func<int, int, int> foox;.

+1

Может показаться правильный способ сделать это? 'Func foox;' – juanchopanza

+2

Даже если это работает, я подозреваю, что это не * правильный путь *, как предполагалось OP. – skypjack

+0

@skypjack Я надеюсь, что это подозрение не заставило вас ответить на этот вопрос: P – cubuspl42

0

Помимо правильного объявления foox (например, упомянутого cubuspl42), вам также не нужно передавать требуемую функцию foo в качестве аргумента конструктора.

Полный код:

#include <iostream> 
#include <functional> 

int foo(int a, int b) { return a+b; }  

template <class R, class... Args> 
class Func{ 
private: 
    std::function<R(Args...)> fn; 
public: 
    Func(std::function<R(Args...)> fnx) : fn(fnx) {} 
    R operator()(Args... a) { return fn(a...); } 

}; 

int main() { 
    Func<int, int, int> foox(foo); 
    std::cout << foox(2,4); 
    return 0; 
} 

`` `

+1

Я думаю, что OP хочет определить свою функцию как 'Func ' вместо 'Func ', как это сделано в его примере. – skypjack

+0

@skypjack Почему бы не спросить OP? – juanchopanza

+0

Ах, вы правы в передаче правильного аргумента конструктору. Вероятно, я найду эту проблему, как только текущая исчезнет. – CygnusX1

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