Mar*_*zzi 5 c++ templates traits c++11 c++14
我有一组类,在每个类中都定义了一个始终具有相同名称的嵌套类。
class A {
public:
class Common {};
...
};
class B {
public:
class Common {};
...
};
Run Code Online (Sandbox Code Playgroud)
我正在尝试编写这样的模板函数(不是编译代码):
template<typename T, typename... ARGS>
void foo(T::Common tc, ARGS... args) {
T t(tc, args...);
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
我想按如下方式使用它:
{
...
A::Common ac();
foo(ac, 42, "Hello");
....
}
Run Code Online (Sandbox Code Playgroud)
如何从传递给函数的内部类实例的类型中提取外部类类型?也许与<traits>,但我对它非常新手......
在您的以下功能模板中:
template<typename T, typename... ARGS>
void foo(T::Common tc, ARGS... args);
Run Code Online (Sandbox Code Playgroud)
T是在不可推论的上下文中。因此,做:
foo(ac, 42, "Hello");
Run Code Online (Sandbox Code Playgroud)
不会编译,因为T不能从函数调用参数中推导出来。您需要显式地将A参数作为参数传递给T模板参数:
foo<A>(ac, 42, "Hello");
Run Code Online (Sandbox Code Playgroud)
但是,请注意,T::Common实际上必须以关键字 开头typename,因为它Common是依赖于类型的名称:
template<typename T, typename... ARGS>
void foo(typename T::Common tc, ARGS... args);
Run Code Online (Sandbox Code Playgroud)
您可以声明一个outer_class_of<>用于提取外部类的类模板。此模板将由内部类类型参数化:
// primary template
template<typename>
struct outer_class_of;
Run Code Online (Sandbox Code Playgroud)
然后,将此模板专门用于A::Common和B:Common:
// specialization for A::Common
template<>
struct outer_class_of<A::Common> {
using type = A; // outer class of A::Common
};
// specialization for B::Common
template<>
struct outer_class_of<B::Common> {
using type = B; // outer class of B::Common
};
Run Code Online (Sandbox Code Playgroud)
然后你可以声明一个别名模板来实现类似 C++14 的_t类型特征:
template<typename T>
using outer_class_of_t = typename outer_class_of<T>::type;
Run Code Online (Sandbox Code Playgroud)
通过这种方式,outer_class_of_t<A::Common>对应于A和outer_class_of_t<B::Common>到B。
最后,您需要将foo()函数模板定义更改为:
template<typename TCommon, typename... ARGS>
void foo(TCommon tc, ARGS... args) {
outer_class_of_t<TCommon> t(tc, args...);
}
Run Code Online (Sandbox Code Playgroud)
当foo()使用 aA::Common或一个B::Common对象作为函数参数调用时,TCommon将分别推导为A::Common或B::Common。outer_class_of<>然后应用TCommon到获取外部类的类型。
另外,请注意C++ 中最令人头疼的解析:
A::Common ac();
Run Code Online (Sandbox Code Playgroud)
你想要的其实是:
A::Common ac{};
Run Code Online (Sandbox Code Playgroud)
否则,在对 的调用中foo(),TCommon将推导出为A::Common(*)()(即:指向函数的指针)而不是A::Common,因为前者声明了一个不带参数并返回一个A::Common对象的函数,而后者实际上声明了一个A::Common对象。
| 归档时间: |
|
| 查看次数: |
301 次 |
| 最近记录: |