Странный случай разрешения перегрузки C++11

Сегодня я столкнулся с довольно странным случаем разрешения перегрузки. Я свел его к следующему:

struct S
{
    S(int, int = 0);
};

class C
{
public:
    template <typename... Args>
    C(S, Args... args);

    C(const C&) = delete;
};

int main()
{
    C c({1, 2});
}

Я вполне ожидал, что C c({1, 2}) будет соответствовать первому конструктору C, при этом количество переменных аргументов будет равно нулю, а {1, 2} будет рассматриваться как конструкция списка инициализаторов объекта S.

Однако я получаю ошибку компилятора, указывающую на то, что вместо этого он соответствует удаленному конструктору копирования из C!

test.cpp: In function 'int main()':
test.cpp:17:15: error: use of deleted function 'C(const C &)'
test.cpp:12:5: error: declared here

Я могу понять, как это может работать - {1, 2} может быть истолкован как допустимый инициализатор для C, причем 1 является инициализатором для S (который неявно конструируется из int, поскольку второй аргумент его конструктора имеет значение по умолчанию), а 2 является переменным аргументом. ... но я не понимаю, почему это было бы лучшим соответствием, особенно учитывая, что конструктор копирования, о котором идет речь, удален.

Не мог бы кто-нибудь объяснить правила разрешения перегрузки, которые здесь действуют, и сказать, есть ли обходной путь, не требующий упоминания имени S в вызове конструктора?

EDIT: Поскольку кто-то упомянул, что фрагмент компилируется другим компилятором, я должен уточнить, что я получил описанную выше ошибку с GCC 4.6.1.

ПРАВКА 2: Я упростил сниппет еще больше, чтобы получить еще более тревожный сбой:

struct S
{
    S(int, int = 0);
};

struct C
{
    C(S);
};

int main()
{
    C c({1});
}

Ошибки:

test.cpp: In function 'int main()':
test.cpp:13:12: error: call of overloaded 'C(<brace-enclosed initializer list>)' is ambiguous
test.cpp:13:12: note: candidates are:
test.cpp:8:5: note: C::C(S)
test.cpp:6:8: note: constexpr C::C(const C&)
test.cpp:6:8: note: constexpr C::C(C&&)

И на этот раз GCC 4.5.1 тоже выдает ту же ошибку (за вычетом constexprов и конструктора move, который он не генерирует неявно).

Мне очень трудно поверить, что это то, что задумали разработчики языка...

9
задан HC4 - reinstate Monica 24 October 2011 в 17:16
поделиться