模板部分排序规则是否未指定?

时间:2016-05-29 00:06:07

标签: c++ templates language-lawyer

我已经注意到很多关于模板的问题,这些问题是由于部分排序规则造成的,而且它们似乎彼此不一致。我以为我会自己深入研究这个标准并把它搞得一团糟。忍受我。

gcc和clang似乎都同意用于确定模板排序的算法,但该算法实际上并未出现在标准中。没有特别的顺序:

推导值的一致性:

template <typename T> void foo(T, T); // (1)
template <typename T, typename U> void foo(T, U); // (2)

temp.deduct.type / 2清楚地表明,Ps必须有一组推导出的值。但是在偏序规则中没有这样的陈述。所描述的算法仅进行成对P / A匹配,因此从(2)到(1)通过foo(U{}, V{})的合成调用可以成功地进行推导。 gcc和clang都认为(1)更专业。

类型合成模板实例化

template <typename T>
struct identity { using type = T; };

template<typename T> void bar(T, T ); // (1) 
template<typename T> void bar(T, typename identity<T>::type ); // (2)

此处,如果为(2)Unique2typename identity<Unique2>::type == Unique2合成,则类型推导将在两个方向上成功,并且调用bar(0,0)将是不明确的。但是,似乎两个编译器只是将typename identity<Unique2>::type视为Unique2_b,从而使模板从(2)到(1)的推断失败(基于隐含的缺失一致性规则)。

非推导上下文省略

与上一个示例相同,但现在定义:

template <typename T> struct identity; template <> struct identity<int> { using type = int; };

在合成和一致性期间没有模板实例化,(2)==&gt; (1)扣除失败。但是如果我们考虑(1)==&gt; (2)致电,我们将TUnique1匹配,然后将未推断的上下文typename identity<Unique1>::typeUnique1匹配,但这将是替代失败。似乎gcc和clang采用的方法(两者都更喜欢这里的)是忽略非推导的上下文参数,只要该参数类型是从匹配的不同模板参数类型推导出来的。 / p>

我在这里有意义吗?

gcc / clang采取的方法是有道理的,但我不认为它在标准中过于清晰。有人可以验证我的逻辑吗?

0 个答案:

没有答案