一段时间后,我再次发现了模板模板参数 的强大功能。参见例如以下片段:
template <template <class> class TT, class T>
void foo(TT<T>) {
}
template <class T>
using typer = T;
int main() {
foo<typer>(int{});
}
别名模板作为模板模板参数传递给模板,并进一步用于检测模板的其他参数,因为它是推断的上下文。美丽!
然而,当需要推导别名模板本身时,编译器看起来就像疯了一样:
template <template <class> class>
struct tag{};
template <template <class> class TT, class T>
void foo(tag<TT>, TT<T>) {
}
template <class T>
using typer = T;
int main() {
foo(tag<typer>{}, int{});
}
编译器当然是对的TT
可以从tag<TT>
中推导出来以及TT<T>
foo
的参数, 和 int{}
与类型参数模式的模板模板不匹配。有什么方法可以保留 T
的推导上下文吗?但是制作TT
TT<T>
中的非推导上下文?
附言我的意图是纯粹的,这只是一个理论问题,背后没有 Y 问题。
最佳答案
我认为这样写会更容易/更清晰:
template <template <class> class TT, class T>
void foo(tag<TT>, T, std::enable_if_t< std::is_same<T,TT<T>>::value >* = 0 )
或限制较少
template <template <class> class TT, class T>
void foo_impl( tag<TT>, TT<T> ){}
template <template <class> class TT, class T>
void foo( tag<TT> a, T b ){ foo_impl<TT>( a, b ); }
作为旁注,这表明标准中声称永远不会推导别名模板名称的(非规范)注释有些不准确......
关于c++ - 有没有一种方法可以将别名模板推导为模板模板参数,同时仍保留其被推导上下文的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46630843/