鉴于以下内容
template <typename T, typename Enable=void>
struct test{};
template <typename T,
typename std::enable_if< some_trait<T>::value >::type >
struct test{};
Run Code Online (Sandbox Code Playgroud)
假设some_trait<T>::value是true, enable_if<T>::type是void,并且选择了专业化.但是,我的查询与以下情况下的选择有关.
template <typename T,
typename std::enable_if_t< some_trait<T>::value,T>::type >
struct test{};
Run Code Online (Sandbox Code Playgroud)
当为第二非空隙模板参数enable_if被设置用于::type,在未特化的模板被选择,即使some_trait<T>::value是true作为::type是T代替void,因此不匹配主模板的默认值.
我的问题是标准中的哪个部分描述了选择模板的顺序,为什么实例test<T,void>被认为是更好的匹配test<T,T>.
完整样本:
#include <iostream>
#include <type_traits>
template <typename T,typename Enable=void>
struct test
{
const char* value = "Primary";
};
#if 1// toggle this
template …Run Code Online (Sandbox Code Playgroud) 我想知道 Visual Studio 2017 和 GCC 中哪个对于标准的以下情况是正确的。问题是,在类模板 Second 中,Visual Studio 中的标识符“Second”始终引用具体类型,但在 gcc 中,它似乎与上下文相关。
海湾合作委员会的例子
template <typename...>
struct type_list{};
template<template <typename...> typename tmpl>
struct tmpl_c
{
template <typename...Ts> using type = tmpl<Ts...>;
};
template<typename> struct template_of;
template <template <typename...> typename tmpl, typename... Ts>
struct template_of<tmpl<Ts...>>{
using type = tmpl_c<tmpl>;
};
template <typename T>
struct first{};
template <typename T>
struct second
{
// 'second' here refers to second<int>
using test = second;
// 'second' here refers to the template second
// is …Run Code Online (Sandbox Code Playgroud) 假设我在编译时要执行一些操作:
enum class Action {A, B};
Run Code Online (Sandbox Code Playgroud)
现在我编写一个模板可变参数函数,它按顺序执行一个可能的动作组合:
template <Action a>
void applyAction();
template <typename = void>
void applyActions() {}
template <Action a, Action... as>
void applyActions() {
applyAction<a>();
applyActions<as...>();
}
Run Code Online (Sandbox Code Playgroud)
这段代码很好.确实:
void foo() {
applyActions<Action::A, Action::B>();
}
Run Code Online (Sandbox Code Playgroud)
正确生成:
call void applyAction<(Action)0>()
call void applyAction<(Action)1>()
Run Code Online (Sandbox Code Playgroud)
为了实现扩展包终止,我不得不声明虚函数:
template <typename = void> void applyActions() {}
Run Code Online (Sandbox Code Playgroud)
这对我来说非常"难看",因为它提供了调用泛型类型的可能性.
在C++ 11中,有没有办法声明一个接受空参数包的可变参数函数?
当然,它的声明不必带来所需函数的模糊性:
template <Action a, Action... as>
void applyActions();
Run Code Online (Sandbox Code Playgroud)
就像是:
template <Action.. = {}>
void applyActions() {}
Run Code Online (Sandbox Code Playgroud)
这是一个不可编译的例子,因为调用含糊不清.但它给出了我想要实现的目标.
c++ templates template-meta-programming variadic-templates c++11