This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: SFINAE question 2
- From: Jonathan Wakely <jwakely dot gcc at gmail dot com>
- To: Onay Urfalioglu <onay dot urfalioglu at gmail dot com>
- Cc: gcc-help at gcc dot gnu dot org
- Date: Wed, 22 Aug 2012 21:37:21 +0100
- Subject: Re: SFINAE question 2
- References: <503529D3.4050403@gmail.com>
On 22 August 2012 19:49, Onay Urfalioglu wrote:
> The following code compiles fine with g++-4.7.1 in c++11 mode, but I think
> it should give errors for the last source line "auto res2 = 2 *
> std::list<int>();" (SFINAE ?)
I don't think it should.
> // compile cmd:
> // g++ c++11-test.cpp -o cpp11-test -std=c++11
>
> #include <vector>
> #include <list>
>
> template<typename T>
> struct HasRandomAccessOp {
> HasRandomAccessOp(const T &v) {
> typedef decltype(v[0]) test_type;
This type is only used in the body of the constructor. That means the
constructor must be instantiated for the error to be detected.
> }
> };
>
> template<typename T, typename T_VECTOR>
> int operator*(const T &l, const T_VECTOR &r) {
> typedef decltype(HasRandomAccessOp<T_VECTOR>(r))
> random_access_test_type;
The constructor doesn't need to be instantiated for decltype to know
the type of that expression, the type is obviously
HasRandomAccessOp<T_VECTOR>.
Even if the constructor was instantiated, SFINAE would not apply,
because the error happens in the function body, not in the context
where template argument deduction takes place, i.e. in determining the
function signature by substituting the template arguments for the
function parameter types and return type.
> return 1;
> }
>
> int main() {
> std::vector<int> iv = {1,2};
>
> auto res1 = 1 * iv;
> auto res2 = 2 * std::list<int>();
> }