Ryan Haining
Ryan Haining

Reputation: 36802

function taking variadic number of initializer_lists with different types

NOTE: this question was caused by a bug in clang


In attemping to write a function taking an arbitrary number of intitializer_lists whose types need not match, I've stumbled upon a strange error:

template <typename... Ts>
void function(std::initializer_list<Ts> &&  ...args){

}

int main() {
    function({1,2,3}, {'h', 'w'}, {"hello", "aloha"});
    return 0;
}

The string literals cause a problem under clang but not under gcc with -pedantic -Wall -Wextra not warning about any extensions.

clang produces the error:

error: no matching function for call to 'function'
    function({1,2,3}, {'h', 'w'}, {"hello", "aloha"});
    ^~~~~~~~
note: candidate function [with Ts = <int, char, char const[6]>] not
      viable: no known conversion from 'const char [6]' to 'char const[6]' for
      3rd argument
void function(std::initializer_list<Ts> &&  ...args){
     ^

So a few questions: Is clang wrong for rejecting this or is gcc using an extension to deduce an initializer_list of arrays? Or is it deeper where gcc is just passing bad code?

Is this is the equivalent of passing an initializer_list of initializer_lists which is of course not allowed?

What is the difference between const char[6] and char const[6]?

Details:

clang version 3.4 (http://llvm.org/git/clang.git 9a65f4251fe5548e0b4478d584796ca84a6f5ebc) (http://llvm.org/git/llvm.git 4f67afc3d67d9a68f1b37767c9c2966a775186bd) Target: x86_64-unknown-linux-gnu Thread model: posix

gcc (Debian 4.7.2-5) 4.7.2

Debian 7

Upvotes: 3

Views: 229

Answers (1)

Casey
Casey

Reputation: 42554

This is a bug in clang: it fails to perform the required array-to-pointer decay when deducing {"hello", "aloha"} against std::initializer_list<Ts>, but only when Ts is a parameter pack.

This program compiles fine:

#include <initializer_list>

template <typename T>
void function(std::initializer_list<T> il) {
}

int main() {
    function({"hello", "aloha", "foobarbaz"});
}

but this program triggers the bug:

#include <initializer_list>

template <typename... T>
void function(std::initializer_list<T>... il) {
}

int main() {
    function({"hello", "aloha", "foobarbaz"});
}

Edit: Could not find this bug in the LLVM bugzilla tracker, submitted as bug# 18047.

Upvotes: 3

Related Questions