我在使用别名模板的上下文中偶然发现了一些关于模板参数推导的行为,我不理解。
基本设置如下:
#include <type_traits>
#include <iostream>
// class-template:
template<typename tpProxy, typename ...tpElements>
struct basic_id {};
// alias template for the above defined class-template:
template<typename tpTypeValue, tpTypeValue ...tpValues>
using value_id = basic_id<std::integral_constant<tpTypeValue, 0>,
std::integral_constant<tpTypeValue, tpValues>...>;
然后我尝试推导出value_id实例化的模板参数(例如在下面显示的特征类模板中)。我的第一种方法是直接在部分模板特化的参数列表中使用value_id别名模板:
// 1st approach of a traits class for value_id:
template<typename tpValueID>
struct is_value_id_1st_approach : std::false_type {};
template<typename tpTypeValue, tpTypeValue ...tpValues>
struct is_value_id_1st_approach<value_id<tpTypeValue, tpValues...>> : std::true_type {};
我的第二种方法,在意识到第一种方法不起作用之后,就是直接将value_id定义写入参数列表,然后对MSVC以及GCC起作用:
// 2nd approach; this time with directly given template-instantiation:
template<typename tpValueID>
struct is_value_id_2nd_approach : std::false_type {};
template<typename tpTypeValue, tpTypeValue ...tpValues>
struct is_value_id_2nd_approach<basic_id<std::integral_constant<tpTypeValue, 0>,
std::integral_constant<tpTypeValue, tpValues>...>> : std::true_type {};
int main() {
using my_value_id = value_id<int, 1, 2, 3>;
std::cout << "is_value_id_1st_approach = " << std::boolalpha <<
is_value_id_1st_approach<my_value_id>::value << std::endl; // false
std::cout << "is_value_id_2nd_approach = " << std::boolalpha <<
is_value_id_2nd_approach<my_value_id>::value << std::endl; // true
}
但是,为什么第一种方法不起作用,第二种方法是什么?
正如Johannes Schaub在相关post中所写的那样:
&#34;他们[别名模板]与等效代码一样可以推导,而不使用模板别名。&#34;
我还定义了另一个别名模板,其中两个方法都起作用:
template<typename ...tpTypes>
using id = basic_id<void, tpTypes...>;
因此,下面的trait类模板能够推导出id实例化的模板参数:
template<typename tpID>
struct is_id : std::false_type {};
template<typename ...tpTypes>
struct is_id<id<tpTypes...>> : std::true_type {};