27

By default, in C++, a single-argument constructor can be used as an implicit conversion operator. This can be suppressed by marking the constructor as explicit.

I'd prefer to make "explicit" be the default, so that the compiler cannot silently use these constructors for conversion.

Is there a way to do this in standard C++? Failing that, is there a pragma (or similar) that'll work in Microsoft C++ to do this? What about g++ (we don't use it, but it might be useful information)?

Roger Lipscombe
  • 89,048
  • 55
  • 235
  • 380

6 Answers6

23

Nope, you have to do it all by hand. It's a pain, but you certainly should get in the habit of making single argument constructors explicit. I can't imagine the pain you would have if you did find a solution and then had to port the code to another platform. You should usually shy away from compiler extensions like this because it will make the code less portable.

Matt Price
  • 43,887
  • 9
  • 38
  • 44
  • 2
    To be honest, we're not too bothered about portability; we're a Windows shop. That's not meant to imply that we don't care; it means that, once you've opted for the Win32 GUI framework, supporting Linux or OSX is academic. – Roger Lipscombe Oct 06 '08 at 14:31
  • 2
    Portability is not just a platform issue. There are other compilers available for windows, eg. Intel, MinGW. There is also backwards compatibility in new versions of Microsofts compiler. The only guarantee you have is that the C++ Committee thinks very carefully before breaking existing C++ code. – Richard Corden Oct 06 '08 at 14:56
  • Just to clarify, I'm not suggesting that Microsoft will break peoples code without thinking, however, they have different pressures to that of the standard's committee. – Richard Corden Oct 06 '08 at 14:57
  • 2
    I've become a big proponent of writing portable code. We've almost always found the more compilers we run our code through the better it becomes. So I've developed a portable mindset that I still adhere to when working in a mono-compiler project. – Matt Price Oct 06 '08 at 15:39
  • 1
    The odds of us using any compiler other than the latest release of Visual C++ are slim. We're just not that bothered about portability, except as an abstract principle. I understand that it's a big deal for others; for us, not so much. – Roger Lipscombe Oct 07 '08 at 08:46
  • How about the intel compiler? Though it strives to be full replacement for Visual Studio's compiler/linker – Matt Price Oct 08 '08 at 15:56
  • `I can't imagine the pain you would have if you did find a solution and then had to port the code to another platform.` What, a text find-and-replace? I agree about striving to use only portable things, but in cases like this (where mechanisms do exist), I don't see much scope for 'unimaginable pain'. Any translation to a different compiler would either have similar syntax in the same position (as an attribute or pragma) or no equivalent (replace with `""`). It's not on the same level as using implementation-defined behaviour or builtins or etc in-code, which could present a real challenge. – underscore_d Sep 23 '16 at 07:27
  • 1
    What gets me is that `explicit` _wasn't the default to start with_. It makes more sense to me for the _default_ behavior of one-arg constructors to be consistent with no-arg and more-arg constructors, and have e.g. an `implicit` keyword instead for constructors where you really want to allow implicit type conversion. (Obviously it's a little late in the game to complain, though. :) – JuSTMOnIcAjUSTmONiCAJusTMoNICa Jun 30 '17 at 16:54
  • Mandatory `explicit` is controversial (read: opinion based). Some love it, some hate it. – Radosław Cybulski Jul 06 '19 at 09:26
2

If there was a pragma or command line option that made constructors explicit by default, how would you declare one that is not explicit? There would have to be another compiler-specific token or pragma to make it possible to declare an implicit conversion constructor.

bk1e
  • 23,871
  • 6
  • 54
  • 65
  • 1
    I like that. It's one of Raymond Chen's rethorical guns. "Can I do this or that? Well, imagine *that you could*, then..." – Johann Gerell Oct 07 '08 at 06:51
  • 1
    I get what you're saying. With a command-line option, this would be true. With a pragma, you could just turn it off later. Or with MSVC, you can use the __pragma or __declspec extensions which could be restricted to the current class (c.f. __declspec(novtable)). – Roger Lipscombe Oct 07 '08 at 14:53
1

It could be rather nasty for any header you have. Like <vector>, or any of the Boost headers. It would also cause quite a few false bugreports. So, no, I don't expect a compiler to add such a #pragma.

MSalters
  • 173,980
  • 10
  • 155
  • 350
1

There is no such option in the compilers, as far as I am aware. But there is a Lint warning for such cases (see http://www.gimpel.com/lintinfo.htm).

MP24
  • 3,110
  • 21
  • 23
0

I think the answer is no!

Sorry, its not a very constructive answer. I hope somebody else might know more!

Scott Langham
  • 58,735
  • 39
  • 131
  • 204
0

There's no such option available in standard c++, and I don't believe there is in Visual Studio either.

luke
  • 36,103
  • 8
  • 58
  • 81