别名模板参数包
aliassing a template parameter pack
我想为参数包使用 using 别名,这样模板就可以在代码库的其他地方使用。在下面的代码中,我注释了我将使用类型的行:
template <typename FirstArg, typename ... OtherArgs>
struct Base {
using UsableFirstArg = FirstArg;
// this would be needed later
// using UsableOtherArgs... = OtherArgs...;
virtual OtherClass method(OtherArgs... a) = 0
};
template <typename DerivedOfBaseInstantiation>
struct CallerStructure {
// to be used here
// OtherClass unknownCall(typename DerivedOfBaseInstantiation::UsableOtherArgs... args) {
// DerivedOfBaseInstantiation instance;
// return instance.method(args...);
// }
}
在 CallerStructure
的代码编写时,unknownCall
的参数未知,由 CallerStructure
的实例化确定,其中 DerivedOfBaseInstantiation
是派生的类型Base
个。在一个看起来像这样的更完整的示例中:
class OtherClass {
};
template <typename FirstArg, typename ... OtherArgs>
struct Base {
using UsableFirstArg = FirstArg;
using UsableOtherArgs... = OtherArgs...;
virtual OtherClass method(OtherArgs... a) = 0;
};
struct Derived_df : Base<int, double, float> {
OtherClass someMethod(Base::UsableFirstArg); // int
OtherClass method(double, float) override ;
};
template <typename DerivedOfBaseInstantiation>
struct CallerStructure {
OtherClass knownCall(typename DerivedOfBaseInstantiation::UsableFirstArg a) {
DerivedOfBaseInstantiation instance;
return instance.someMethod(a);
}
OtherClass unknownCall(typename DerivedOfBaseInstantiation::UsableOtherArgs... args) {
DerivedOfBaseInstantiation instance;
return instance.method(args...);
}
};
void instantiations() {
CallerStructure<Derived_df> c;
[[maybe_unused]] auto a = c.knownCall(42);
[[maybe_unused]] auto b = c.unknownCall(23., 11.f);
}
关于如何为 CallerStructure
中的方法接口访问 Base
的可变参数模板的任何提示?
您不能为可变模板参数设置别名。您可以将它们包装在 std::tuple
:
template <typename FirstArg, typename ... OtherArgs>
struct Base {
using UsableFirstArg = FirstArg;
using UsableOtherArgs = std::tuple<OtherArgs...>;
virtual OtherClass method(OtherArgs... a) = 0;
};
展开需要一些帮助:
template <typename DerivedOfBaseInstantiation,
typename = typename DerivedOfBaseInstantiation::UsableOtherArgs>
struct CallerStructure;
template <typename DerivedOfBaseInstantiation, typename ... OtherArgs>
struct CallerStructure<DerivedOfBaseInstantiation, std::tuple<OthersArgs...>> {
OtherClass knownCall(typename DerivedOfBaseInstantiation::UsableFirstArg a) {
DerivedOfBaseInstantiation instance;
return instance.someMethod(a);
}
OtherClass unknownCall(OtherArgs... args) {
DerivedOfBaseInstantiation instance;
return instance.method(args...);
}
};
我想为参数包使用 using 别名,这样模板就可以在代码库的其他地方使用。在下面的代码中,我注释了我将使用类型的行:
template <typename FirstArg, typename ... OtherArgs>
struct Base {
using UsableFirstArg = FirstArg;
// this would be needed later
// using UsableOtherArgs... = OtherArgs...;
virtual OtherClass method(OtherArgs... a) = 0
};
template <typename DerivedOfBaseInstantiation>
struct CallerStructure {
// to be used here
// OtherClass unknownCall(typename DerivedOfBaseInstantiation::UsableOtherArgs... args) {
// DerivedOfBaseInstantiation instance;
// return instance.method(args...);
// }
}
在 CallerStructure
的代码编写时,unknownCall
的参数未知,由 CallerStructure
的实例化确定,其中 DerivedOfBaseInstantiation
是派生的类型Base
个。在一个看起来像这样的更完整的示例中:
class OtherClass {
};
template <typename FirstArg, typename ... OtherArgs>
struct Base {
using UsableFirstArg = FirstArg;
using UsableOtherArgs... = OtherArgs...;
virtual OtherClass method(OtherArgs... a) = 0;
};
struct Derived_df : Base<int, double, float> {
OtherClass someMethod(Base::UsableFirstArg); // int
OtherClass method(double, float) override ;
};
template <typename DerivedOfBaseInstantiation>
struct CallerStructure {
OtherClass knownCall(typename DerivedOfBaseInstantiation::UsableFirstArg a) {
DerivedOfBaseInstantiation instance;
return instance.someMethod(a);
}
OtherClass unknownCall(typename DerivedOfBaseInstantiation::UsableOtherArgs... args) {
DerivedOfBaseInstantiation instance;
return instance.method(args...);
}
};
void instantiations() {
CallerStructure<Derived_df> c;
[[maybe_unused]] auto a = c.knownCall(42);
[[maybe_unused]] auto b = c.unknownCall(23., 11.f);
}
关于如何为 CallerStructure
中的方法接口访问 Base
的可变参数模板的任何提示?
您不能为可变模板参数设置别名。您可以将它们包装在 std::tuple
:
template <typename FirstArg, typename ... OtherArgs>
struct Base {
using UsableFirstArg = FirstArg;
using UsableOtherArgs = std::tuple<OtherArgs...>;
virtual OtherClass method(OtherArgs... a) = 0;
};
展开需要一些帮助:
template <typename DerivedOfBaseInstantiation,
typename = typename DerivedOfBaseInstantiation::UsableOtherArgs>
struct CallerStructure;
template <typename DerivedOfBaseInstantiation, typename ... OtherArgs>
struct CallerStructure<DerivedOfBaseInstantiation, std::tuple<OthersArgs...>> {
OtherClass knownCall(typename DerivedOfBaseInstantiation::UsableFirstArg a) {
DerivedOfBaseInstantiation instance;
return instance.someMethod(a);
}
OtherClass unknownCall(OtherArgs... args) {
DerivedOfBaseInstantiation instance;
return instance.method(args...);
}
};