Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can operators be overloaded for initializer_list literals? [duplicate]

I am trying to overload operators for std::initializer_list, but the following compiles neither in GCC 4.7.2 nor Clang 3.2:

#include <initializer_list>

void operator+(const std::initializer_list<int>&, const std::initializer_list<int>&);

int main() {
   {1, 2} + {3, 4};
}

13.5/6 says that an operator function shall have at least one parameter whose type is a class, enum, or reference to either, and the standard specifies initializer_list as a template class, so to me it seems like it should be conformant. However, apparently both Clang and GCC think I'm trying to use their non-standard block expressions.

GCC:

Compilation finished with errors:
source.cpp: In function 'int main()':
source.cpp:7:8: warning: left operand of comma operator has no effect [-Wunused-value]
source.cpp:7:9: error: expected ';' before '}' token
source.cpp:7:9: warning: right operand of comma operator has no effect [-Wunused-value]
source.cpp:7:13: error: expected primary-expression before '{' token
source.cpp:7:13: error: expected ';' before '{' token

Clang:

Compilation finished with errors:
source.cpp:7:5: warning: expression result unused [-Wunused-value]
   {1, 2} + {3, 4};
    ^
source.cpp:7:9: error: expected ';' after expression
   {1, 2} + {3, 4};
        ^
        ;
source.cpp:7:8: warning: expression result unused [-Wunused-value]
   {1, 2} + {3, 4};
       ^
source.cpp:7:13: error: expected expression
   {1, 2} + {3, 4};
            ^
2 warnings and 2 errors generated.

Should this compile? If not, why not?

EDIT:

And not surprisingly, the November CTP of VS 2012 fails as well:

error C2143: syntax error : missing ';' before '}'
error C2059: syntax error : '{'
error C2143: syntax error : missing ';' before '{'
like image 670
Seth Carnegie Avatar asked Jan 16 '13 23:01

Seth Carnegie


1 Answers

As far as I understand 13.5/6,

An operator function shall either be a non-static member function or be a non-member function and have at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration

this should not be possible. Braced-init-lists are not the same as std::initializer_lists, and they're not interchangeable. The following should work, though:

std::initializer_list<int>({1,2}) + std::initializer_list<int>({2,1})

Or this:

operator+({1,2}, {2,1})

Update: To clarify, the point is that there's no rule in the language grammar that allows a braced-init-list to appear in the context suggested by the OP. Braced-init-lists can only appear in contexts where some­thing is about to be initialized, if you will.

like image 96
Kerrek SB Avatar answered Sep 21 '22 20:09

Kerrek SB