Consider the following C++11 code:
template <typename T>
class optional_ref {
public:
optional_ref() : ref_(nullptr) {}
optional_ref(const T& ref) : ref_(&ref) {}
bool has_value() const { return ref_ != nullptr; }
const T& value() const { return *ref_; }
private:
const T* ref_;
};
class stream_t {};
template <typename T, unsigned long N>
void copy(T(&destination)[N], optional_ref<const stream_t> stream = {}) // !!!
{ destination[0] = 1; }
This code compiles fine with g++; but - MSVC doesn't like it for some reason, giving the following errors regarding the line marked !!!
:
error C2065: 'destination': undeclared identifier
error C2275: 'optional_ref<const stream_t>': expected an expression instead of a type
error C2146: syntax error: missing ')' before identifier 'stream'
error C2143: syntax error: missing ';' before '{'
error C2143: syntax error: missing ')' before ';'
error C2447: '{': missing function header (old-style formal list?)
error C2059: syntax error: ')'
error C2447: '{': missing function header (old-style formal list?)
It seems like it is having some trouble with the array-reference parameter. But - what is it actually complaining about?
I would appreciate some input from someone with more MSVC experience, who may be able to better decipher this sequence of errors.
Consider the following C++11 code:
template <typename T>
class optional_ref {
public:
optional_ref() : ref_(nullptr) {}
optional_ref(const T& ref) : ref_(&ref) {}
bool has_value() const { return ref_ != nullptr; }
const T& value() const { return *ref_; }
private:
const T* ref_;
};
class stream_t {};
template <typename T, unsigned long N>
void copy(T(&destination)[N], optional_ref<const stream_t> stream = {}) // !!!
{ destination[0] = 1; }
This code compiles fine with g++; but - MSVC doesn't like it for some reason, giving the following errors regarding the line marked !!!
:
error C2065: 'destination': undeclared identifier
error C2275: 'optional_ref<const stream_t>': expected an expression instead of a type
error C2146: syntax error: missing ')' before identifier 'stream'
error C2143: syntax error: missing ';' before '{'
error C2143: syntax error: missing ')' before ';'
error C2447: '{': missing function header (old-style formal list?)
error C2059: syntax error: ')'
error C2447: '{': missing function header (old-style formal list?)
It seems like it is having some trouble with the array-reference parameter. But - what is it actually complaining about?
I would appreciate some input from someone with more MSVC experience, who may be able to better decipher this sequence of errors.
This looks like a MSVC bug, you can report it to Microsoft here. In the meantime, aliasing the array as another type works for me:
template <typename T, size_t N>
using dest_array = T[N];
// Function template
template <typename T, size_t N>
void copy(dest_array<T, N>& destination, span<T const> source, optional_ref<const stream_t> stream = {})
{
...
}
Link to Godbolt example to verify it works on latest MSVC: https://godbolt./z/nb76MdP4c. Thanks!
This seems to be an MSVC bug, which I have now filed as:
MSVC rejects syntax of reference to C array as a function parameter
Will update if/when it's fixed.
Credit to this answer from Anis Ladram, who suggested this as a compiler bug.