单独的判决模板:template<... sep ...>

separate verdict template: teplate<... sep ...>

我想分离一个判断模板,我在 Ubuntu 上使用 clang++4.0,我有以下代码:

#include <iostream>
#include <experimental/array>

using std::array;

struct Dummy {
};

template<int _I, int ... _rest>
constexpr bool test(int _test) {
if constexpr (sizeof...(_rest) == 0) {
    return (_test % _I);
} else {
    return (_test % _I && test<_rest...>(_test));
}
}

template< int ... _I>
constexpr array<int, sizeof...(_I)> make_array() {
return { {_I...}};
}

template<int ... _primes, typename _d, int _test, int ... _todo>
constexpr auto make_prime_array_helper() {
if constexpr (test<_primes...>(_test)) {
    if constexpr (sizeof...(_todo) == 0) {
        return make_array<_primes..., _test>();
    } else {
        return make_prime_array_helper<_primes..., _test, _d, _todo...>();
    }
} else {
    if constexpr (sizeof...(_todo) == 0) {
        return make_array<_primes...>();
    } else {
        return make_prime_array_helper<_primes..., _d, _todo...>();
    }
}
}

template<int _I0, int _I1,int _I2,int _I3, int ... _todo> // 0, 1, 2, 3 ....
constexpr auto make_prime_array() {
return make_prime_array_helper<_I2, _I3 , Dummy, _todo...>();
}

int main() {
constexpr auto a = make_prime_array<0, 1, 2, 3, 5>();
std::cout << a[1] << std::endl;
return 0;
}

但它不起作用,我得到一个错误:

../src/primearray.cpp:44:9: error: no matching function for call to 'make_prime_array_helper'
        return make_prime_array_helper<_I2, _I3 , Dummy, _todo...>();
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/primearray.cpp:49:21: note: in instantiation of function template specialization 'make_prime_array<0, 1, 2, 3, 5>' requested here
        constexpr auto a = make_prime_array<0, 1, 2, 3, 5>();
                           ^
../src/primearray.cpp:25:16: note: candidate template ignored: invalid explicitly-specified argument for template parameter '_primes'

我尝试将 typename _d 更改为 bool _d 之类的其他内容,但出现此错误:

../src/primearray.cpp:24:16: note: candidate template ignored: couldn't infer template argument '_d'

可以这样做吗?

您可以通过函数参数推导其中一个模板参数包来完成此操作。例如。对您的代码进行以下小修改:

#include <iostream>
#include <experimental/array>

using std::array;

template<int... _primes> 
struct PrimeSeq {
};

template<int _I, int... _rest>
constexpr bool test(int _test) {
    if constexpr (sizeof...(_rest) == 0) {
        return (_test % _I);
    } else {
        return (_test % _I && test<_rest...>(_test));
    }
}

template< int ... _I>
constexpr array<int, sizeof...(_I)> make_array() {
    return { {_I...}};
}

template<int _test, int... _todo, int... _primes>
constexpr auto make_prime_array_helper(PrimeSeq<_primes...>) {
    if constexpr (test<_primes...>(_test)) {
        if constexpr (sizeof...(_todo) == 0) {
            return make_array<_primes..., _test>();
        } else {
            return make_prime_array_helper<_todo...>(PrimeSeq<_primes..., _test>{});
        }
    } else {
        if constexpr (sizeof...(_todo) == 0) {
            return make_array<_primes...>();
        } else {
            return make_prime_array_helper<_todo...>(PrimeSeq<_primes...>{});
        }
    }
}

template<int _I0, int _I1,int _I2,int _I3, int... _todo> // 0, 1, 2, 3 ....
constexpr auto make_prime_array() {
    return make_prime_array_helper<_todo...>(PrimeSeq<_I2, _I3>{});
}

int main() {
    constexpr auto a = make_prime_array<0, 1, 2, 3, 5>();
    std::cout << a[1] << std::endl;
    return 0;
}

会完成这项工作。通过 clang++-4.0 -std=c++1z

编译时它工作正常