2014-08-27 126 views
1

我有函数指针型或函数原型:模板:通过函数原型确定模板参数

int function (int arg); 
typedef int (*function_t) (int arg); 

和模板类像

template <typename T_ret, typename... T_args> 
class caller { 
    T_ret (*m_p) (T_args... args); 
public: 
    T_ret call (T_args... args) { 
     return m_p(args); 
    } 
    caller (T_ret (*p)(T_args...args)) : m_p(p) {} 
}; 

是否有可能使编译器会自动确定内模板参数代码像

class caller2 : public caller <__something_with_function_prototype__> { 
    caller2 : caller (function) {}; 
}; 

而类似的问题:是否有可能做t他的,但与另一个模板类而不是功能?

template <typename T_ret, typename... T_args> class example; 
typedef example<int, int> example_t; 

谢谢。

+0

的SOLU重刑是[这里](http://ideone.com/TxYh3X) – shved 2014-08-28 15:05:53

回答

1

不知道这是否是你想要的,但也许:

#include <iostream> 

int function (int arg) { return arg; } 
typedef int (*function_t) (int arg); 

template <typename T_ret, typename... T_args> 
class caller { 
    T_ret (*m_p) (T_args... args); 
public: 
    T_ret call (T_args... args) { 
     return m_p(args...); 
    } 
    caller (T_ret (*p)(T_args...args)) : m_p(p) {} 
}; 

template <typename T_ret, typename... T_args> 
caller<T_ret, T_args...> get_caller(T_ret(*prototype)(T_args...)) 
{ 
    return caller<T_ret, T_args...>(prototype); 
} 

int main() 
{ 
    function_t f = &function; 
    auto c = get_caller(f); 
    std::cout << c.call(1) << std::endl; 
    return 0; 
} 

Live demo link.

或可能:

#include <iostream> 

int function (int arg) { return arg; } 
typedef int (*function_t) (int arg); 

template <typename T> 
class caller {}; 

template <typename T_ret, typename... T_args> 
class caller<T_ret(*)(T_args...)> { 
    T_ret (*m_p) (T_args... args); 
public: 
    T_ret call (T_args... args) { 
     return m_p(args...); 
    } 
    caller (T_ret (*p)(T_args...args)) : m_p(p) {} 
}; 

int main() 
{ 
    caller<decltype(&function)> c(&function); 
    std::cout << c.call(1) << std::endl; 
    return 0; 
} 

Yet another live demo link.

+0

第二个是我需要的,但我必须重新定义我的模板类,以便与函数和其他模板类一起使用。我已经有了两个定义:一般T_ret和T_ret = void。我能否以某种方式避免这种复杂性? – shved 2014-08-28 13:44:52

+0

@shved:你的意思是这样的:http://ideone.com/e0zpJW? – 2014-08-28 13:51:57

+0

@Pirot:绝对。现在我有两个这样的定义。如果我想使用它,例如'caller >',我必须再添加两个。有什么办法可以避免这种情况? – shved 2014-08-28 13:56:21

1

你可以使用一些辅助:

template <typename F> struct helper; 

template <typename T_ret, typename... T_args> 
struct helper<T_ret (*) (T_args... args)> 
{ 
    using type = caller<T_ret, T_args...>; 
}; 

,然后用它像

int function (int arg); 

class caller2 : public helper<decltype(&function)>::type { 
public: 
    caller2() : caller (&function) {} 
}; 

而且是更通用:

template <typename T_ret, typename... T_args> 
struct helper<T_ret (*) (T_args... args)> 
{ 
    template <template <typename, typename...> class C> 
    using type = C<T_ret, T_args...>; 
}; 

然后

class caller2 : public helper<decltype(&function)>::type<caller> { 
public: 
    caller2() : caller (&function) {} 
}; 

helper<decltype(&function)>::type<example>example<int, int>

+0

谢谢,这工作完美,它解决了问题,但使用代码变得更加复杂。 – shved 2014-08-28 13:41:08

+0

顺便说一句,你可以使用'function_t'而不是'decltype(&function)',因为它们是相同的类型。 – Jarod42 2014-08-28 13:54:24

+0

因此,通过您和@Piotr的帮助,我可以解决此问题,例如[this](http://ideone.com/TxYh3X)。谢谢。 – shved 2014-08-28 15:04:57

相关问题