3

This compiles:

template <typename... Ts>
void function(std::string name, const Ts&... files) {
    // do stuff with Ts, which is NOT ensured to be a child class of std::string
}

According to this answer I wrote the following code in my class:

template <typename Base, typename T, typename... Ts>
struct are_base_of : std::conditional<std::is_base_of<Base, T>::value, are_base_of<Base, Ts...>, std::false_type>::type {};
template <typename Base, typename T>
struct are_base_of<Base, T> : std::is_base_of<Base, T> {};

Now this compiles:

template <typename... Ts>
typename std::enable_if<are_base_of<std::string, Ts...>::value, void>::type
function(std::string name, const Ts&... files) {
    // do stuff with Ts, which is ensured to be a child class of std::string
}

This doesn't compile:

template <typename... Ts, typename std::enable_if<are_base_of<std::string, Ts...>::value>>
void function(std::string name, const Ts&... files) {
    // do stuff with Ts, which is ensured to be a child class of std::string
}

The error is:

error C3547: template parameter 'unnamed-parameter' cannot be used because it follows a template parameter pack and cannot be deduced from the function parameters of 'MyClass::function'

Why...? And how can I fix it?

康桓瑋
  • 33,481
  • 5
  • 40
  • 90
traveh
  • 2,700
  • 3
  • 27
  • 44
  • Related: [Is it legal to use an unexpanded parameter pack as the type of a template template parameter's non-type template parameter?](https://stackoverflow.com/questions/71453755/is-it-legal-to-use-an-unexpanded-parameter-pack-as-the-type-of-a-template-templa/71454485#71454485) and also [GCC & Clang vs MSVC Bug while expanding template parameter pack in the same parameter clause for function templates](https://stackoverflow.com/questions/71893166/gcc-clang-vs-msvc-bug-while-expanding-template-parameter-pack-in-the-same-para) – Jason Oct 24 '22 at 07:47
  • Also note that the program can be ill-formed no diagnostic required if you don't actually use the function templates. Compilers have the freedom to give a diagnostic or not. So, to really confirm that a compiler is rejecting the code, you must first actually use that template(class or function). – Jason Oct 24 '22 at 07:56
  • You're just not using `enable_if` properly (you never gave it a default, so it's just a template parameter with no value). In C++14, write `std::enable_if_t::value, int> = 0`. In C++17, write `std::enable_if_t<(std::is_base_of_v && ...), int> = 0`. In C++20, write `template ... Ts> void function(std::string name, const Ts&&... files)`. – Artyer Oct 24 '22 at 07:59

0 Answers0