能否根据所使用的构造函数定义成员typedef?
无法直接实现,原因及替代方案
不行,你没法根据对象使用的构造函数来定义类的成员typedef。核心原因是:类的成员typedef是编译期确定的属性,属于模板实例化后的类类型本身,和具体对象的构造方式完全无关。
当你写C c1(&func)或者C c2(4)时,编译器会先根据推导的模板参数T=int实例化出C<int>这个类类型,此时C<int>::Type就已经固定了——所有C<int>的对象都会共享这个typedef,不管你用哪个构造函数创建对象。构造函数是运行时创建对象的逻辑,没法影响编译期就确定的类成员类型。
替代方案:通过额外模板参数区分类型
如果想要达到“不同构造方式对应不同的Type”的效果,可以给类模板加一个额外的标记参数,再用工厂函数来隐藏细节,自动选择对应的类实例:
#include <iostream> #include <type_traits> template<typename T, bool UseConst = false> struct C { // 根据标记参数选择Type using Type = std::conditional_t<UseConst, const T, T>; // 用requires限制构造函数和标记参数的匹配 explicit C(void (*ptr)(T)) requires UseConst { } explicit C(T) requires (!UseConst) { } }; // 工厂函数:根据参数类型自动选择对应的C实例 template<typename T> auto make_C(void (*ptr)(T)) { return C<T, true>(ptr); } template<typename T> auto make_C(T val) { return C<T, false>(val); } void func(int); int main() { auto c1 = make_C(&func); // c1的类型是C<int, true>,Type为const int auto c2 = make_C(4); // c2的类型是C<int, false>,Type为int // 验证类型是否符合预期 static_assert(std::is_same_v<decltype(c1)::Type, const int>); static_assert(std::is_same_v<decltype(c2)::Type, int>); }
这样一来,通过make_C创建的对象,会根据传入的参数自动匹配对应的类实例,从而拥有不同的Type成员。
内容的提问来源于stack exchange,提问作者user20562802
相关产品推荐
相关产品推荐

