c++ - 有没有一种方法可以将别名模板推导为模板模板参数,同时仍保留其被推导上下文的属性

标签 c++ templates template-templates template-aliases

一段时间后,我再次发现了模板模板参数 的强大功能。参见例如以下片段:

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{});
}

[live demo]

编译器当然是对的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/

相关文章:

c++ - 推断/删除模板模板参数的类型

c++ - 有没有一种方法可以确保继承的成员在派生类中不可访问,同时仍然保留公共(public)继承的好处?

c++ - 如何创建会抛出堆栈溢出异常的无限递归?

c++ - 我们可以重载 malloc() 吗?

c++ - 匹配别名模板作为模板参数

c++ - 通过模板-模板参数使用枚举标记对象

c++ - 可变参数模板模板和完美转发

c++ - 如何从库函数访问 C++ 中的 argc 和 argv

c++ - 如何在模板函数签名中要求 const_iterator 语义?

c++ - 函数模板的多个实例与参数列表匹配