首页 > 解决方案 > 模板别名的相等性

问题描述

我尝试创建无法与原始别名区分开来的模板别名。

因此,我创建了特征来检查 2 个模板(不是类型)何时相等:

template <template <class...> class C1,
          template <class...> class C2>
struct is_same_template : std::false_type {};

template <template <class...> class C1>
struct is_same_template<C1, C1> : std::true_type {};

现在测试它:

// Expected alias
template <typename ... Ts> using V_Ts = std::vector<Ts...>;    // Variadic
// Fallback alias
template <typename T, typename A> using V = std::vector<T, A>; // Exact count

static_assert(!is_same_template<std::vector, V_Ts>::value); // Alias rejected by gcc/clang
static_assert( is_same_template<std::vector, V>::value);    // Alias accepted only for gcc

演示

是否可以创建“真实”别名?哪个编译器是对的?

标签: c++language-lawyertemplate-templatesusing-declaration

解决方案


我尝试创建无法与原始别名区分开来的模板别名。

我认为目前这是不可能的。(不幸的是)没有模板别名,只有别名模板。别名模板始终是它自己的模板[temp.alias]/1。别名模板的特化等效于通过将模板参数替换为别名模板而获得的类型,但别名模板本身并不是另一个模板[temp.alias]/2的别名。我会考虑 GCC 让你的第二次static_assert通过 GCC 中的一个错误……

正如@HolyBlackCat 在上面的评论中所指出的,有一个相关的问题和答案指出了许多相关的 CWG 问题。特别是一个问题 ( CWG 1286 ) 似乎表明希望允许别名模板本身等同于它在某些情况下引用的模板。但是,由于后来提出的担忧,拟议的决议似乎并未获得通过。当前标准草案中的相关措辞([temp.alias][temp.type])似乎与 C++11 没有变化……</p>


推荐阅读