I wrote a Signal/Slot library (Codeproject article here), under linux, compiling with both Clang 3.5 and GCC4.9. It compiles without warnings on both compilers (also on versions 3.4 resp 4.8). When I got it all working, and posted the article online, it wasn't long until I got complaints that it's not working on MSVC. (Visual Studio Express 2013? I'm sorry, I'm not familiar with the versioning system.) I installed it in a VM to have a look for myself and found that it won't compile the following:
template <typename Signature>
struct RemoveCV;
template <typename R, typename ... Args>
struct RemoveCV<T, R (Args...)>
{
using Type = R(Args...);
};
template <typename R, typename ... Args>
struct RemoveCV<T, R(Args...) const>
{
using Type = R(Args...);
};
// more specializations for volatile and const volatile
// Usage:
template <typename Signature_>
struct Function
{
using Signature = RemoveCV<Signature_>::Type;
};
// both Function<void()> and Function<void() const> now have
// the same Signature: void()
The reason being that R(Args ...)
is not a member function, so it can't have a const
qualifier.
While it is of course true that it doesn't make sense to have a const
qualifier on a non-memberfunction, I believe I read somewhere (here on SO, including a quote from the standard), that it is allowed as long as it's not bound to an actual function. I.e. it is allowed as a stand-alone type. Unfortunately I don't seem to be able to find that thread anymore...
I was just wondering who's right on this occasion: MSVC or GCC + Clang, and what the standard has to say about a standalone function signature like void() const
.
Well, I believe that it appears that you (and GCC and Clang) are right, with regards to what the standard says. From §8.3.5/6 (in N3376), (emphasis mine):
A cv-qualifier-seq or a ref-qualifier shall only be part of:
— the function type for a non-static member function,
— the function type to which a pointer to member refers,
— the top-level function type of a function typedef declaration or alias-declaration,
— the type-id in the default argument of a type-parameter (14.1), or
— the type-id of a template-argument for a type-parameter (14.2).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With