Variadic函数不会用clang编译

PYA*_*PYA 3 c++ templates language-lawyer c++11

首先,我道歉,如果这是重复,我会很乐意把它删除,但我甚至不确定这里的问题/诊断是什么.

无论如何,我的代码在这里使用gcc而不是clang - 为什么会这样?我显然无法理解为什么clang不能编译它.

#include <iostream>
#include <type_traits>

using std::cout;
using std::endl;


template <typename T, typename... Args, typename std::enable_if<!sizeof...(Args)>::type* = nullptr>
void func(int start_size, int idx)
{
    cout << start_size << " " << idx << endl;
    return;
}

template <typename T, typename... Args, typename std::enable_if<sizeof...(Args)>::type* = nullptr>
void func(int start_size, int idx)
{

    if((idx + 1) == int(start_size - int(sizeof...(Args))))
       {
           cout << start_size << " " << idx << endl;
           return;
       }
       func<Args...>(start_size, idx);
}

template <typename... Args>
void func_wrapper(int idx)
{
    func<Args...>(sizeof...(Args),idx);
}


int main()
{
    func_wrapper<int,double,char>(1);

}
Run Code Online (Sandbox Code Playgroud)

错误:

prog.cc:37:5: error: no matching function for call to 'func'
    func<Args...>(sizeof...(Args),idx);
    ^~~~~~~~~~~~~
prog.cc:44:5: note: in instantiation of function template specialization 'func_wrapper<int, double, char>' requested here
    func_wrapper<int,double,char>(1);
    ^
prog.cc:16:6: note: candidate template ignored: requirement '!sizeof...(Args)' was not satisfied [with T = int, Args = <double, char>]
void func(int start_size, int idx)
     ^
prog.cc:23:6: note: candidate template ignored: substitution failure [with T = int, Args = <double, char>]: non-type template argument evaluates to 2, which cannot be narrowed to type 'bool'
void func(int start_size, int idx)
     ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

Wandbox:https://wandbox.org/permlink/yqki47uYcwUlE013

lll*_*lll 7

clang在拒绝此代码时是正确的.要消除错误,您应该明确应用转换:

std::enable_if<bool(sizeof...(Args))>
Run Code Online (Sandbox Code Playgroud)

理由是:

[temp.arg.nontype]/5

对用作非类型模板参数的每个表达式执行以下转换.如果非类型模板参数无法转换为相应模板参数的类型,则程序格式错误.

(5.1)对于整数或枚举类型的非类型模板参数,应用转换常量表达式([expr.const])中允许的转换.

然后[expr.const]/3表示不会自动考虑缩小转换:

T类型的转换常量表达式是一个文字常量表达式,隐式转换为类型T,其中隐式转换(如果有)在文字常量表达式中是允许的,而隐式转换序列仅包含用户定义的转换,lvalue-to- rvalue转换([conv.lval]),整数促销([conv.prom])和整数转换([conv.integral]),而不是缩小转化次数([dcl.init.list])

因此,对于这种情况,缩小转换std::size_tbool,应该是明确的:bool(sizeof...(Args))

  • 更好的是:`enable_if <sizeof ...(Args)!= 0>` (3认同)
  • 查找标准的@PYA是你通过尝试和失败获得的技能.继续尝试;)很快就会有一部分你可以感觉到答案是否可以隐藏. (2认同)