How to disallow temporaries

后端 未结 10 1689
一个人的身影
一个人的身影 2020-12-02 05:19

For a class Foo, is there a way to disallow constructing it without giving it a name?

For example:

Foo(\"hi\");

And only allow it i

相关标签:
10条回答
  • 2020-12-02 05:42

    Simply don't have a default constructor, and do require a reference to an instance in every constructor.

    #include <iostream>
    using namespace std;
    
    enum SelfRef { selfRef };
    
    struct S
    {
        S( SelfRef, S const & ) {}
    };
    
    int main()
    {
        S a( selfRef, a );
    }
    
    0 讨论(0)
  • 2020-12-02 05:45

    Since the primary goal is to prevent bugs, consider this:

    struct Foo
    {
      Foo( const char* ) { /* ... */ }
    };
    
    enum { Foo };
    
    int main()
    {
      struct Foo foo( "hi" ); // OK
      struct Foo( "hi" ); // fail
      Foo foo( "hi" ); // fail
      Foo( "hi" ); // fail
    }
    

    That way you can't forget to name the variable and you can't forget to write struct. Verbose, but safe.

    0 讨论(0)
  • 2020-12-02 05:50

    A few years ago I wrote a patch for the GNU C++ compiler which adds a new warning option for that situation. This is tracked in a Bugzilla item.

    Unfortunately, GCC Bugzilla is a burial ground where well-considered patch-included feature suggestions go to die. :)

    This was motivated by the desire to catch exactly the sort of bugs that are the subject of this question in code which uses local objects as gadgets for locking and unlocking, measuring execution time and so forth.

    0 讨论(0)
  • 2020-12-02 05:53

    Another macro-based solution:

    #define Foo class Foo
    

    The statement Foo("hi"); expands to class Foo("hi");, which is ill-formed; but Foo a("hi") expands to class Foo a("hi"), which is correct.

    This has the advantage that it is both source- and binary-compatible with existing (correct) code. (This claim is not entirely correct - please see Johannes Schaub's Comment and ensuing discussion below: "How can you know that it is source compatible with existing code? His friend includes his header and has void f() { int Foo = 0; } which previously compiled fine and now miscompiles! Also, every line that defines a member function of class Foo fails: void class Foo::bar() {}")

    0 讨论(0)
  • 2020-12-02 05:55

    How about a little hack

    class Foo
    {
        public:
            Foo (const char*) {}
    };
    
    void Foo (float);
    
    
    int main ()
    {
        Foo ("hello"); // error
        class Foo a("hi"); // OK
        return 1;
    }
    
    0 讨论(0)
  • 2020-12-02 05:56

    Make the constructor private but give the class a create method.

    0 讨论(0)
提交回复
热议问题