template<class T, class... TA> Uptr<T, TA> makeUniquePtr(/*...*/) { /*...*/ };
template<class T, class... TA> Sptr<T, TA> makeSharedPtr(/*...*/) { /*...*/ };
template<typename TFPType, TFPType TFP> void func(/*...*/) { /*...*/ }
template<class T, class... TA> void implementation1(/*...*/)
{
// Can this be reduced to func<&makeUniquePtr, T, TA...>?
func<decltype(&makeUniquePtr<T, TA...>), &makeUniquePtr<T, TA...>>(/*...*/);
}
template<class T, class... TA> void implementation2(/*...*/)
{
// Can this be reduced to func<&makeSharedPtr, T, TA...>?
func<decltype(&makeSharedPtr<T, TA...>), &makeSharedPtr<T, TA...>>(/*...*/);
}
调用func</*...*/>(/*...*/)
非常详细。有没有办法简单地调用
func<&makeSharedPtr, T, TA...>(/*...*/)
并在内部使用
&makeSharedPtr<T, TA...>
没有用户指定它两次?
答案 0 :(得分:4)
创建一个共享的制造商无状态函数对象类,如std::less
,但本身没有template
参数:而是operator()
完美转发到您的template
函数。
传递它而不是你的函数指针。
如果您需要传递template
个参数,请为其创建static
方法,或让整个template class
获取参数并在operator()
中使用它们
以下是后期绑定template
参数(live example)的示例:
#include <iostream>
// test stubs:
template<typename... Ts>
using UPtr = int;
template<typename... Ts>
using SPtr = double;
template<typename T, typename...TA>
UPtr<T,TA...> makeUniquePtr() {
std::cout << "makeUniquePtr\n";
return {};
}
template<typename T, typename...TA>
SPtr<T,TA...> makeSharedPtr() {
std::cout << "makeSharedPtr\n";
return {};
}
// perfect forwarding make static functions passed by class name:
struct unique_ptr_maker {
template<typename T, typename...TA, typename...Args>
static UPtr<T, TA...> make(Args&&...args) {
return makeUniquePtr<T, TA...>( std::forward<Args>(args)... );
}
};
struct shared_ptr_maker {
template<typename T, typename...TA, typename...Args>
static SPtr<T, TA...> make(Args&&...args) {
return makeSharedPtr<T, TA...>( std::forward<Args>(args)... );
}
};
// your `func`. It can take args or whatever:
template<typename maker, class T, class... TA> void func() {
std::cout << "func\n";
maker::template make<T, TA...>();
}
// a sample of implementation 1 and 2:
template<class T, class... TA> void implementation1()
{
func<unique_ptr_maker, T, TA...>();
}
template<class T, class... TA> void implementation2()
{
func<shared_ptr_maker, T, TA...>();
}
// and, to test, always instantiate:
int main() {
implementation1<int, double>();
implementation2<int, char>();
return 0;
}
大部分功能已被删除,因为你没有详细说明你的问题应该做什么。
答案 1 :(得分:1)
从你的名字做一些关于预期用途的假设,我会尝试这样的事情:
template<class T>
struct makeUniquePtr {
template<class... TA>
Uptr<T, TA> operator()(TA&&...) const { /*...*/ }
};
template<class T>
struct makeSharedPtr {
template<class... TA>
Sptr<T, TA> operator()(TA&&...) const { /*...*/ }
};
template<class F> void func(/*...*/) { /*...*/ }
template<class T, class... TA> void implementation1(/*...*/)
{
func<makeUniquePtr<T>>(/*...*/);
}
template<class T, class... TA> void implementation2(/*...*/)
{
func<makeSharedPtr<T>>(/*...*/);
}
与Yakk's solution不同,此处会自动推导出参数TA...
,例如std::make_unique等。
编辑我在编辑解决方案之前就提到了Yakk的解决方案。我现在看到它已经扩展。