c – 模板参数包在Clang上失败但在VS 2015上失败

我正在研究一个函数,该函数调用带有可变数量参数的提供函数.它在Visual Studio 2015上编译并正常工作,但无法在Clang上编译.我准备了一个演示,展示了我想要做的事情.我在Clang得到的错误是:

prog.cpp: In function ‘int main()’: prog.cpp:31:2: error: no matching
function for call to ‘run(std::vector&, void ()(int&, const
int&), const int&)’ ); ^ prog.cpp:7:6: note: candidate:
template void
run(std::vector&, const std::function&,
mutrArgs …) void run(
^ prog.cpp:7:6: note: template argument deduction/substitution failed: prog.cpp:31:2: note: mismatched types ‘const
std::function’ and ‘void (
)(int&, const
int&)’ );

#include <functional>
#include <iostream>
#include <vector>
using namespace std;

template<int RepeatTimes, class ... mutrArgs>
void run(
    vector<int>& vec,
    const function<void(int&, mutrArgs ...)>& mutr,
    mutrArgs ... args
)
{
    for (int times{0} ; times < RepeatTimes ; ++times)
        for (auto& item : vec)
            mutr(item, args...);
}

void adder(int& i, const int& val)
{
    i += val;
}

int main()
{
    vector<int> v{0,1,2,3,4,5,6,7,8,9};
    const int addValue{4};
    run<2, const int&>(
        v,
        &adder,
        addValue
    );
    for (auto i : v)
        cout << i << " ";
    cout << endl;
    return 0;
}

最佳答案 运行< 2,const int&>只是陈述第一个参数,但不会停用演绎.

run<2, const int&>(v, &adder, addValue);

有两个地方推断出mutrArgs:

> addValue – > mutrArgs = {const int& }
>& adder,它不是std :: function,因此失败.

采取功能解决问题的地址

auto call_run = &run<2, const int&>;
call_run(v, &adder, addValue);

奇怪的是,clang不支持与gcc相反的内联用法:/

(&run<2, const int&>)(v, &adder, addValue);

如果要禁用扣减,可以使模板arg不可扣除:

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

template <typename T> using non_deducible_t = typename identity<T>::type;

然后

template<int RepeatTimes, class ... mutrArgs>
void run(
    std::vector<int>& vec,
    const std::function<void(int&, non_deducible_t<mutrArgs> ...)>& mutr,
    non_deducible_t<mutrArgs> ... args
)

Demo

即使在你的情况下,Joachim Pileborg建议的简单类型名称F似乎更好.

点赞