Late for the party, but I think I found a way to define and use a class only instantiable on stack. I must admit its use is rather limited, as you can only:
- take it as a const reference and
- call its const member functions and
- read its data members.
There is no way, however, to use it in a new expression or allocate it with dynamic storage duration as a member of another object (like Steve Folly shows in his answer).
Example implementation:
class StackOnly
{
const char* _str{ "" };
StackOnly() = default;
StackOnly(const StackOnly&) = default;
constexpr StackOnly(const char* str) : _str{ str } {};
public:
template <typename ...Args>
constexpr static StackOnly create(Args&&... args)
{ return StackOnly{ std::forward<Args>(args)... }; }
void print() const { std::cout << _str; }
};
Please note that even though its limits, object still can be used quite decently, if you … well … use it in a function:
void useStackOnly(const StackOnly& obj)
{
// function extends the lifetime of our temporary :)
const StackOnly& stackObj = obj;
stackObj.print();
}
int main()
{
useStackOnly(StackOnly::create("greetings from stack"));
}
Note 1: The object itself might allocate on heap and use mutable data members - technically you can make up a vector :).
Note 2: C++11 is not required. One can achieve this in older C++ revisions as well.