5

I have one class that holds a shared_ptr to another class. I am getting a compilation error with the shared_ptr declaration that says "no members defined using this type." My code to duplicate this is very short:

#include <iostream>
#include <boost/shared_ptr.hpp>

class MyClassImpl
{
};

class MyClass
{
public:
    boost::shared_ptr<MyClassImpl> _sptr;
    //error C2208: 'boost::shared_ptr<T>' : no members defined using this type
};


int main()
{
    MyClass mc;

    return 0;
}

What am I doing wrong here? I'm Visual Studio Professional 2010 with Boost 1.54.

user2023861
  • 8,030
  • 9
  • 57
  • 86

4 Answers4

10

There's no error in your code: it's (surprise) an error in Microsoft's compiler. Apparently _sptr is some kind of magic identifier. Change the name and it will compile correctly (Live at Rextester).

Here's a minimal example that shows the problem:

struct A {
    int _sptr;
};

int main()
{}

This answer implies that both _sptr and _uptr have this effect in Visual C++, I haven't been able to find an authoritative source.

Microsoft does document an extension that implements modifiers __sptr and __uptr that perform some magic when converting 32-bit pointer types to 64-bit pointer types. I assume that the compiler is treating _sptr and _uptr the same as __sptr and __uptr. I've submitted this on Connect as Bug# 882592.

Microsoft's response:

We agree that it is unfortunate for the compiler to disallow the use of these specific identifiers, but it is cost prohibitive to fix this bug in our current implementation due to architectural reasons. In the meantime, please work around this issue by using other names for your variables.

Community
  • 1
  • 1
Casey
  • 41,449
  • 7
  • 95
  • 125
  • I'll be damned. Who would've guessed? I changed it to _ssptr and it compiled with no other changes. – user2023861 May 28 '14 at 15:13
  • @RaydelMiranda If I knew what a PolyMathic was I could possibly speculate as to why it works fine. – Casey May 28 '14 at 15:18
  • @Casey I ask him for the version of the compiler and he is using Xcode, not VS, that's why the code works for him. Good catch!! +1 – Raydel Miranda May 28 '14 at 15:19
1

The answer of Casey above is good. The problem with underscore is well known. There are a lot of discussions on stackoverflow. See, for example, rules-about-using-an-underscore about details, which are quite complex. But there is very nice and simple "Personal rule" which was formulated by paercebal in that discussion (paercebal's answer):

Because I did not want to deal with cases, and wanted a simple rule, I have designed a personal one that is both simple and correct:

When naming a symbol, you will avoid collision with compiler/OS/standard libraries if you:

never start a symbol with an underscore

never name a symbol with two consecutive underscores inside. 
Community
  • 1
  • 1
SergV
  • 1,269
  • 8
  • 20
0

From MSDN - Microsoft Compiler Error C2208:

An identifier resolving to a type name is in an aggregate declaration, but the compiler cannot declare a member.

The following sample generates C2208:

// C2208.cpp
class C {
   C;   // C2208
   C(){}   // OK
};

Try to add a default constructor to MyClassImpl and MyClass.

Raydel Miranda
  • 13,825
  • 3
  • 38
  • 60
0

I encountered "no members defined using this type" from MSVC with this code:

Foo<Bar<Baz,int> qux; 

This was fixed by making sure that every angle bracket had a mate:

Foo<Bar<Baz,int>> qux;

Not the asker's situation, but I thought I might leave it here in case other brilliant people do what I did.

MatrixManAtYrService
  • 8,023
  • 1
  • 50
  • 61