【问题标题】:Is substitution performed on a variadic parameter pack type if the pack is empty?如果包为空,是否对可变参数包类型执行替换?
【发布时间】:2012-05-09 18:27:21
【问题描述】:

考虑以下程序:

#include <type_traits>

enum class dummy {};
template <typename T>
using EnableIf = typename std::enable_if<T::value, dummy>::type;
template <typename T>
using DisableIf = typename std::enable_if<!T::value, dummy>::type;

template <typename T>
struct dependent_true_type : std::true_type {};

template <typename T,
          EnableIf<dependent_true_type<T>>...>
std::true_type f();
template <typename T,
          DisableIf<dependent_true_type<T>>...>
std::false_type f();

static_assert(decltype(f<int>())::value, "");

int main() {}

GCC 4.7 高兴接受这个程序。我最近的 clang 3.1 版本声称对 f 的调用不明确。

test.c++:22:24: fatal error: call to 'f' is ambiguous
static_assert(decltype(f<int>())::value, "");
                       ^~~~~~
test.c++:17:16: note: candidate function [with T = int, $1 = <>]
std::true_type f();
               ^
test.c++:20:17: note: candidate function [with T = int, $1 = <>]
std::false_type f();
                ^
1 error generated.

如果我写f&lt;int, dummy{}&gt;(),它确实接受程序。

当包为空时,似乎clang没有考虑参数包的类型,这导致没有将其从候选集中删除。即使包为空,GCC 似乎也会对参数包类型执行替换,并且由于所述替换因一次重载而失败,因此没有歧义。

这两个哪个是正确的?

【问题讨论】:

    标签: c++ c++11 g++ clang sfinae


    【解决方案1】:

    我相信我已经找到了相关的标准语。 §14.8.2p7 说:

    替换发生在函数类型和模板参数声明中使用的所有类型和表达式中。

    由于在模板参数声明中使用了EnableIf&lt;dependent_true_type&lt;T&gt;&gt;,因此应该进行替换,这是a bug in clang

    【讨论】:

    • 能否请您评论 PR 并添加您的测试用例?恕我直言,您的测试用例更为关键,因为它发生在参数推导期间(我的测试用例仅在参数推导后遗漏了替换)并且因为 clang 与 gcc 不同。
    猜你喜欢
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 2014-12-15
    • 2015-08-09
    • 1970-01-01
    • 2016-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多