0

Why does the std library not use these instead? Currently if a call is made to the copy constructor on a non-copyable object, the error message can be a little 'cryptic' or confusing to someone who has never encountered one before.

The first time I had this error message I had no idea what the problem was (I never thought of the idea of inaccessible ctors) until I looked up the class and saw "non-copyable" and finally understood.

what were the benefits of making the copy-ctor private? It is still visible in VS intellisense for ctor overloads.

why did they not simply choose to:

public:
someClass(const someClass&) { static_assert(false, "someClass is of non-copyable type. calls to copy constructor are disallowed."); }

if someone tries to compile their code they will see this error message, which states the reason of the error more explicitly. Compared to (const someClass&) is inaccessible. Imagine how difficult it would be to understand this when heavy use of templates are involved?

so, what benefits are there to a private copy-ctor vs a static_assert?

Igneous01
  • 719
  • 1
  • 10
  • 24
  • static_assert is available since C++11. Probably the std library was written using C++03. – Spoonwalker Highwater Jun 20 '13 at 01:52
  • 1
    How exactly do you expect this to work? The class won't compile, no matter what. The `static_assert` is checked by trying to compile the class code, not by calling it. – Benjamin Lindley Jun 20 '13 at 02:39
  • it works on VS2012. unordered_map also uses it when a type without a hashing function is provided. The class compiles on my end, it only fails when I call copy-ctor or assignment. – Igneous01 Jun 20 '13 at 11:42
  • @David: If you are using it in a template, then it works because VS [doesn't properly implement two-phase look-up](http://stackoverflow.com/questions/6273176/what-exactly-is-broken-with-microsoft-visual-cs-two-phase-template-instanti). And no, `unordered_map` doesn't do what you are doing. It doesn't pass `false` directly to `static_assert`. It passes a value that is computed based on the key. – Benjamin Lindley Jun 20 '13 at 15:04
  • 1
    Here's a more relevant link: http://stackoverflow.com/questions/14637356/static-assert-fails-compilation-even-though-template-function-is-called-nowhere – Benjamin Lindley Jun 20 '13 at 15:16

2 Answers2

2
  1. The reason of cryptic messages is a problem of compiler, not C++, although that's true that for C++ implementing good messages is harder. Clang provides much better error messages than other compilers, for example.

  2. I don't know why MS decided to show private overloads in VS intellisense - but that's definitely not a С++ problem but a problem of IDE (or there is some hidden, unknown for me sense).

  3. static_assert is supported only in C++11 and it would require to change even more standard specs just to change error message.

  4. Private constructor is more idiomatic in C++ than custom static_asserts.

  5. This suggestion doesn't even make any sense. The static_assert will cause a compiler error. Always. Whether anyone tries to call the copy constructor or not. (As pointed out by @BenjaminLindley in comments)

sasha.sochka
  • 14,395
  • 10
  • 44
  • 68
  • fair enough, for older libraries this makes sense, but for thread, future, packaged_task, and promise, it would be reasonable to implement a static_assert instead, since they are all apart of c++11 – Igneous01 Jun 20 '13 at 02:06
  • 2
    5. This suggestion doesn't even make any sense. The `static_assert` will cause a compiler error. Always. Whether anyone tries to call the copy constructor or not. – Benjamin Lindley Jun 20 '13 at 02:42
2

In C++11 there is a better way:

someClass(const someClass&) = delete;

Unfortunately, MSVC does not support it yet.

But, maybe there is hope:

Yep, I was super busy getting the STL ready for VS 2013 Preview. I've got a VCBlog draft with a detailed changelog that I'll be able to publish after the Build conference.

Jesse Good
  • 50,901
  • 14
  • 124
  • 166