VC++ compiler and type deduction

I tried to compile on VC++/VS17 a program that I had previously compiled on GCC and Clang without problem. VS17 is generating a whole bunch of errors. It seems that VC++ is struggling with type deduction in the context class specialization using SFINAE.

What is going on ?

The following is an example of a code fragment that compiles without issue under GCC and Clang but fails under VC++.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <stdlib.h>
#include <vector> 


template<typename T>
using if_lvalue = typename std::enable_if<std::is_lvalue_reference<T>::value, std::nullptr_t>::type;

template<typename T>
using if_reverse_iterator = decltype(std::declval<T>().rbegin(), nullptr);

template<class C, typename valuetype = std::nullptr_t, typename X = std::nullptr_t>
class reverser;

template< class C >
class reverser<C, if_lvalue<C>, if_reverse_iterator<C>>
{
public:

protected:
	C& collection;
	typedef decltype(collection.rbegin()) iterator;
public:
	iterator begin() { return collection.rbegin(); }
	iterator end() { return collection.rend(); }
	reverser(C & v) : collection(v) {}
};


template<class T>
reverser<T&> make_reverser(T& v) {
	return reverser<T&>(v);
}


int main() {
	std::vector<int> v = { 1,2,3,4,5,6 };
	auto m1 = make_reverser(v);
	for (auto i : m1) { std::cout << i << ", "; }
	std::cout << std::endl;
}
Last edited on
Copied and pasted your code into VS2017 and it compiled without even a warning.
The following errors came up on CodeMirror using VC++.

source_file.cpp(38): error C2027: use of undefined type 'reverser<std::vector<int,std::allocator<_Ty>> &,std::nullptr_t,std::nullptr_t>'
        with
        [
            _Ty=int
        ]
source_file.cpp(38): error C2514: 'reverser<std::vector<int,std::allocator<_Ty>> &,std::nullptr_t,std::nullptr_t>': class has no constructors
        with
        [
            _Ty=int
        ]
source_file.cpp(39): error C2027: use of undefined type 'reverser<std::vector<int,std::allocator<_Ty>> &,std::nullptr_t,std::nullptr_t>'
        with
        [
            _Ty=int
        ]
source_file.cpp(39): error C2065: 'i': undeclared identifier
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64


https://rextester.com/IYQC89393
Last edited on
Thanks for looking into this, problem solved!

The conformance mode needed to be set to -permissive. According to this article. They changed the default project setting starting with VS17 version 15.5, and I was still using version 15.4.

https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=vs-2017

Initially, I didn't bother upgrading VC17 because my code was plain old C++11 and it seemed that even the 2017 version of VC++ should be able to handle it.
I was still using version 15.4

The current VS version is 15.9.7, updated this week. The conformance mode -permissive is now default.

I didn't bother upgrading VC17 because my code was plain old C++11 and it seemed that even the 2017 version of VC++ should be able to handle it.

Default language standard with VS17 is C++14, not C++11.

At least one thing that I know of was deprecated in C++14, and removed in C++17, std::random_shuffle in <algorithm>.
Registered users can post here. Sign in or register to post.