有没有办法将别名模板推导到模板模板参数,同时仍保留其推导上下文的属性

W.F*_*.F. 8 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{});
}
Run Code Online (Sandbox Code Playgroud)

别名模板作为模板模板参数传递给模板,并进一步用于检测模板的其他参数,因为它是推导的上下文.美女!

然而,当需要推断别名模板本身时,看起来编译器会变得疯狂:

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{});
}
Run Code Online (Sandbox Code Playgroud)

[现场演示]

编译器当然是正确的,TT可以从两者tag<TT>以及TT<T> 参数中推断出来foo,并且int{}模板模板与类型参数模式不匹配.有没有办法保留演绎上下文T但是在TT非演绎语境中TT<T>

PS我的意图是纯粹的,这只是一个理论问题,背后没有Y问题.

Mas*_*nes 3

我认为写这样的东西会更容易/更清晰:

template <template <class> class TT, class T>
void foo(tag<TT>, T, std::enable_if_t< std::is_same<T,TT<T>>::value >* = 0 )
Run Code Online (Sandbox Code Playgroud)

或约束较少的

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 ); }
Run Code Online (Sandbox Code Playgroud)

作为旁注,这表明标准中声称永远不会推导别名模板名称的(非规范)注释有些不准确......