c++20 msvc error c3861 base member not found - c++20

i have a strange problem since i switched the C++ language standard in VS2022 for my c++ project from 17 to 20.
I get compiler error C3861 identifier not found. The indentifier in this case is a member of the base class.
base class:
template <class C> class base_vector
{
public:
base_vector()
{
}
virtual ~base_vector()
{
}
protected:
std::vector<C> m_vec;
};
derived class:
template <class C> class child_vector : public base_vector<C>
{
public:
child_vector()
{
}
virtual ~child_vector()
{
m_vec.clear(); // c3861
}
};
When i switch the standard to c++17, no compiler error.
m_vec should be known in child_vector but it's not.
Can anyone see the problem ?
Many thanks

m_vec is a member of a base class dependent on the template parameters.
Until instantiation of the template, the compiler cannot know that m_vec is indeed a member of the base class, but it must do name lookup for m_vec when parsing the template definition, because m_vec isn't a dependent name.
You need to use this->m_vec explicitly. this is dependent and this form will delay the name lookup until the template parameters and the base class are known.
That has also been the case before C++20. By default MSVC does however do name lookup in a non-standard-compliant way, which is why it works by default. To get the standard-compliant behavior you need to give MSVC the /permissive- flag. With the /std:c++20 flag or later, that flag is implied. (https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-170)

Related

Can I add 'operations' to runtimeclass in a winrt component

In the below code "RuntimeMethod1()" is an operation. It does not take any input parameters and does not give back any result.
Is this kind of method allowed in a runtime class?
I am getting compilation error for this runtime class. It says
expecting an identifier near "(" at line 7
namespace UniversalRuntimeComponent
{
[default_interface]
runtimeclass Class
{
Class();
RuntimeMethod1();
Int32 RuntimeMethod2(Int32 arg1);
String RuntimeMethod3(String arg1);
}
}
If I remove "RuntimeMethod1()" from the class then it compiles fine and generates the projection and implementation types.
If it doesn't return a result then make its return type void.
Change line 7 in your IDL to the following:
void RuntimeMethod1();
Then either copy and paste the method from auto generated .h file or just add it manually.
With the exception of constructors, all methods in MIDL 3.0 need to declare a return type. The documentation has the following to say on methods:
A method has a (possibly empty) list of parameters, which represent values or variable references passed to the method. A method also has a return type, which specifies the type of the value computed and returned by the method. A method's return type is void if it doesn't return a value.
You will have to change the MIDL to the following:
namespace UniversalRuntimeComponent
{
[default_interface]
runtimeclass Class
{
Class();
void RuntimeMethod1();
Int32 RuntimeMethod2(Int32 arg1);
String RuntimeMethod3(String arg1);
}
}
Note, that the data types declared in MIDL follow MIDL specification. This is not strictly related to the Windows Runtime type system, although all MIDL data types map to data types that can be represented in the Windows Runtime type system.
Also note, that all methods in the Windows Runtime have at least one return value at the ABI. A method declared using void in MIDL will still return an HRESULT to communicate error or success.

Error when calling static method c++

Consider the following code:
Automobile.h
class Automobile
{
static string m_stCityCode;
static bool CheckCityCode(const Automobile& obj);
};
Automobile.cpp
bool Automobile::CheckCityCode(const Automobile& obj)
{
return m_stCityCode == obj.m_stCityCode;
}
int main()
{
//do something
}
I get the following error
"Severity Code Description Project File Line Suppression State
Error LNK2001 unresolved external symbol "public: static class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > Automobile::m_stCityCode"
(?m_stCityCode#Automobile##2V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##A) myPro C:\Users\zhivko.rusev\Documents\Visual
Studio 2015\Projects\myPro\myPro\Calls.obj 1 "
I would appreciate every help for solving this problem. Thanks in advance!
The static member needs to be defined. The error message is the linker's way of telling you it isn't. Your code declares the static member but does not define it.
To define it, in a single compilation unit (i.e. a non-header source file) simply add a line at file scope after including the header file
#include "Automobile.h"
std::string Automobile::m_stCityCode = ""; // change the initialiser to whatever suits
Do this in exactly one compilation unit. One is necessary to define the symbols. Multiple definitions (e.g. in multiple source files within your project) will cause the linker to complain about symbols being defined multiple times.
There are other problems in your code as shown, beyond what you have asked about, but I'll assume that just reflects you having left information out.

Move semantics and std::unique_ptr in chaiscript

How can I register a method that relies on move semantics and std::unique_ptr with chaiscript's engine? Here's an example piece of code I cannot get to work using chaiscript 5.8.5 :
class Element;
class MyClass
{
public:
void addElement(std::unique_ptr<Element>&&);
};
chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());
chaiscript::utility::add_class<MyClass>(*m, "MyClass", {
chaiscript::constructor<MyClass ()>()
}, {
{chaiscript::fun(&MyClass::addElement), "addElement"},
});
This generates the following error from within chaiscript:
dispatchkit/boxed_cast_helper.hpp:43:46: error: 'type name' declared as a pointer to a reference of type 'std::__1::unique_ptr
std::__1::default_delete > &&' return *static_cast(p);
r-values and unique_ptr now have support in the develop branch (to become version 6.0.0) of ChaiScript, but at the time this question was asked it was not possible.

How to declare static field in class

I have a XAML + DirectX app and I want to add static field to my "interop" class:
[Windows::Foundation::Metadata::WebHostHidden]
public ref class Direct3DInterop sealed : public Windows::Phone::Input::Interop::IDrawingSurfaceManipulationHandler
{
public:
static int VALUE = 0;
...
};
It does not compile saying "only static const integral data members can be initialized within a class".
If I change it to const static int VALUE = 0; then it still does not compile with error "a non-value type cannot have any public data members"
What am I doing wrong?
WinRT public classes have a number of limitations to ensure they are consumable by multiple languages including C++, JavaScript, and C#. This is why you are getting error C3984. You can't have public fields and instead must use properties. You'd make it a read-only property:
property int VALUE
{
int get() { return 0; }
}
It is important to remember that properties are function calls and can't usually be optimized away, so you should consider that when designing the interfaces.
If you intend to have this class only consumable by C++, consider not using a WinRT class and instead use a simple C++ class which you managed the lifetime using std::unique_ptr or std::shared_ptr. In that case, you can of course use the public field approach as always.
The original problem you got is a general C++ language restriction not specific to WinRT. Error C2864 (you are using VS 2012 from the text you posted) is a little more general with C++11 in VS2013.

Using constants as default parameter values in interfaces: IDE okay but mxmlc fails?

This code seems to compile fine in the IDE, but the command-line compiler (SDK 4.5 mxmlc.exe) reports "Parameter initializer unknown or is not a compile-time constant."
senocular gives a good explanation and a maybe-workaround, but I'm hoping for something more elegent (like a command-line instruction).
package {
public class Constants {
public static const CONSTANT : int = 0;
}
}
package {
public interface IInterface {
function foo( param : int = Constants.CONSTANT ) : void;
}
}
package
{
public class Concrete implements IInterface
{
public function foo(param:int=Constants.CONSTANT):void
{
}
}
}
According to Senocular, it's all about the compilation order. There's no explicit way to set this order.
You could define inline constants using the define compiler option to avoid this problem.
Another way would be to create a library containing the constants. Libraries are included before user classes.
To create a library use the component compiler:
compc -output lib\Constants.swf -source-path src -include-classes Constants
When compiling the application, include that library:
mxmlc -include-libraries lib\Constants.swf -- src\Main.as
Just don't forget to recompile the library when the constants change, or use a build script that takes care of that.
A short comment on the example code:
The interface doesn't need to use that constant, any value will do and have the same effect on implementing classes.
Programming AS3 - Interfaces
A method that implements such a function declaration must have a default parameter value that is a member of the same data type as the value specified in the interface definition, but the actual value does not have to match.