指向构造函数重载的指针?
Pointer to constructor overload?
我有一堆遗留代码,如下所示:
#define MAKE_FOO_FNS(fooname) \
fooname* makeFoo_ ## fooname ## A(A arg) { \
return new fooname(arg); \
} \
fooname* makeFoo_ ## fooname ## B(B arg) { \
return new fooname(arg); \
} \
// ... repeated many more times
以便稍后在代码中我们可以说:
MAKE_FOO_FNS(FooType1);
MAKE_FOO_FNS(FooType2);
然后可以访问以下类型的函数指针:
FooType1* (*)(A);
FooType1* (*)(B);
FooType2* (*)(A);
FooType2* (*)(B);
我知道我可以用模板替换 MAKE_FOO_FNS
:
template<typename FooType>
FooType* makeFooA(A arg) {
return new FooType(arg);
}
// .. etc ..
这样我们就可以从 &MakeFooA<FooType1>
、&MakeFooA<FooType2>
等中获取函数指针,而无需任何宏 hackery。
但这似乎仍然是不必要的样板文件 --- 是否有一种 (C++11) 方法可以在不编写所有这些包装函数的情况下直接获取指向 "invoking operator new
of FooType1
with the constructor that takes an A
" 的函数指针?
是的,只需使用 lambda。无捕获 lambda 可以隐式转换为函数指针:
X*(*p)(A) = [](A arg){ return new X(arg); };
如果你想要更少的打字和更高的安全性,你也可以指向 std::make_unique
的正确专业化:
auto p2 = std::make_unique<X, A>;
您可以将所有 makeFooA<>()、makeFooB<>() 等函数合并到一个通用模板中:
template<typename T, typename... Args>
T* make_ptr(Args&&... args)
{
return new T(std::forward<Args>(args)...);
}
这样的优点是现在可以传递多个参数(通过值或通过引用),缺点是在获取地址时需要指定完整签名,即 &make_ptr.
注意,如果你有boost,你不需要自己实现:http://www.boost.org/doc/libs/1_61_0/libs/functional/factory/doc/html/
我有一堆遗留代码,如下所示:
#define MAKE_FOO_FNS(fooname) \
fooname* makeFoo_ ## fooname ## A(A arg) { \
return new fooname(arg); \
} \
fooname* makeFoo_ ## fooname ## B(B arg) { \
return new fooname(arg); \
} \
// ... repeated many more times
以便稍后在代码中我们可以说:
MAKE_FOO_FNS(FooType1);
MAKE_FOO_FNS(FooType2);
然后可以访问以下类型的函数指针:
FooType1* (*)(A);
FooType1* (*)(B);
FooType2* (*)(A);
FooType2* (*)(B);
我知道我可以用模板替换 MAKE_FOO_FNS
:
template<typename FooType>
FooType* makeFooA(A arg) {
return new FooType(arg);
}
// .. etc ..
这样我们就可以从 &MakeFooA<FooType1>
、&MakeFooA<FooType2>
等中获取函数指针,而无需任何宏 hackery。
但这似乎仍然是不必要的样板文件 --- 是否有一种 (C++11) 方法可以在不编写所有这些包装函数的情况下直接获取指向 "invoking operator new
of FooType1
with the constructor that takes an A
" 的函数指针?
是的,只需使用 lambda。无捕获 lambda 可以隐式转换为函数指针:
X*(*p)(A) = [](A arg){ return new X(arg); };
如果你想要更少的打字和更高的安全性,你也可以指向 std::make_unique
的正确专业化:
auto p2 = std::make_unique<X, A>;
您可以将所有 makeFooA<>()、makeFooB<>() 等函数合并到一个通用模板中:
template<typename T, typename... Args>
T* make_ptr(Args&&... args)
{
return new T(std::forward<Args>(args)...);
}
这样的优点是现在可以传递多个参数(通过值或通过引用),缺点是在获取地址时需要指定完整签名,即 &make_ptr.
注意,如果你有boost,你不需要自己实现:http://www.boost.org/doc/libs/1_61_0/libs/functional/factory/doc/html/