0

I have a class that requires a const size_t parameter in its constructor. It works as intended when I use it to declare a variable on the stack. But I get a compiler error if I use it to declare a member of another class. Typically, I get "unknown type name" when I use a named variable for the parameter, or "Expected ')'" when I use an integer constant.

The parameter isn't used for allocation; it is simply stored in a member variable.

This tiny program segment illustrates the problem:

#include <iostream>
#include "QuickBin.h"

class useless
{
    const size_t m_size;
public:
    useless(const size_t s) : m_size(s)
    {
    }
    QuickBin m_store1(m_size); // Unknown type name 'm_size'
    QuickBin m_store2(40); // Expected a right paren
};

int main(int argc, const char * argv[]) {
    QuickBin locker(40); // No problem here; this works fine
    std::cout << "Hello, World!\n";
    return 0;
}



And here is the constructor for QuickBin:

QuickBin::QuickBin(const size_t s)
{
    m_size = s;
}



I feel certain that I am missing something obvious, because I get errors on this code both from Visual Studio and from Xcode. My final solution has to be compatible with C++11.

There is other stuff in the actual class but it is irrelevant to this problem. No memory allocation takes place. I've gotten bleary-eyed in the last 2 days trying to find documentation to cover this and I have come up empty. I'll emphasize that even when I have used a named variable as a parameter, it is a constant whose value is known at compile time. Any ideas?

Logicrat
  • 4,438
  • 16
  • 22
  • That's because it's not valid C++. Neither does using it "to declare a variable on the stack" is valid C++ either, but a non-standard extension supported by some C++ compilers. Your C++ textbook will have more information, but the long and the short of it is that C++ simply does not work this way. All objects in C++ have a fixed size that's determined ***at compile time***, and not based on any other non-constexpr variable. – Sam Varshavchik Nov 04 '21 at 21:09
  • @SamVarshavchik I was confident with the dupe, but now I'm not. Where does it have a non-standard extension? – Yksisarvinen Nov 04 '21 at 21:14
  • @SamVarshavchik I agree, the size is fixed at compile time. That's why (1) I have only used values known at compile time and (2) the parameter is not involved in sizing. It is only stored as a `size_t` member, whose size is known at compile time. – Logicrat Nov 04 '21 at 21:15
  • https://stackoverflow.com/questions/1887097/ – Sam Varshavchik Nov 04 '21 at 21:15
  • `size_t s` is not known at compile time. It could be 10. Or it could be 50. How is it "known at compile time"? – Sam Varshavchik Nov 04 '21 at 21:15
  • @SamVarshavchik Two things: (1) My question has nothing to do with variable-size arrays, and (2) `m_size` is `const size_t` set by `s`. In use, every invocation of QuickBin uses a known constant as a parameter. – Logicrat Nov 04 '21 at 21:23
  • @Logicrat I've no idea what Sam is trying to tell, but the answer to your question is to use uniform initialiation `QuickBin m_store1{m_size};` or equals initialization `QuickBin m_store1 = QuickBin(m_size);`. You cannot use parantheses for default class member initialization. See the duplicate question (at the top of the page) for the reasoning. Also, docs for this topic can be found [here](https://en.cppreference.com/w/cpp/language/data_members#Member_initialization). – Yksisarvinen Nov 04 '21 at 21:26
  • Unfortunately that means every invocation of `QuickBin` could be using a different number, and that means the number isn't constant as far as a VLA is concerned. I don't see where the VLA is creeping in, though. Maybe was there in a previous edit? – user4581301 Nov 04 '21 at 21:27
  • @user4581301 There is no VLA. SamVarsavchick mentioned it a few times though. And I did intend for each invocation to use its own number. – Logicrat Nov 04 '21 at 21:56
  • @user4581301 For what it's worth, your suggestion worked fine in Xcode (C++14) but neither form worked in VS2010 (C++11). I ended up sidestepping the problem by declaring a pointer to QuickBin as a member and then initializing that member in the constructor, and recoding all uses for `->` pointer notation. Ugly, but it works. – Logicrat Nov 04 '21 at 22:23
  • I think you wanted to poke @Yksisarvinen , not me. – user4581301 Nov 04 '21 at 22:33

0 Answers0