How do you define ref in C++/CLI?
In C#, we can write:
public override void myfunction(TokenStream tokenStream, ref string outliningKey,
ref OutliningNodeAction tokenAction);
So in C++/CLI, I tried to write:
public:virtual void myfunction(TokenStream ^ tokenStream,
ref String ^ outliningKey, ref OutliningNodeAction tokenAction)override
I want to define String ^ outliningKey AND OutliningNodeAction tokenAction to ref
in C++/CLI, but we don't have any ref keyword in C++/CLI.
Can anyone help me to define myfunction Variable to ref mod?
Use this syntax:
public: virtual void myfunction(String ^% outliningKey) { .... }
Related
I would like to define a member function in a class template only if traits contain type and use type as its argument like that:
struct A {};
struct B { using type = int; };
template <typename T>
concept has_type = requires { typename T::type; };
template <typename Traits>
struct Handler
{
void set(typename Traits::type)
requires has_type<Traits>
{}
};
Unfortunately, typename Traits::type is parsed before the requires clause and it fails to compile if type does not exist (struct A):
<source>:19:14: error: no type named 'type' in 'struct A'
19 | void set(typename Traits::type)
I could only come up with this alternative, which looks excessively cumbersome:
template <typename Traits>
struct Handler
{
template <typename Type>
requires has_type<Traits> && std::same_as<Type, typename Traits::type>
void set(Type)
{}
};
It also fails to compile under clang (although I expected it to short-circuit), but gcc compiles it correctly:
<source>:20:78: error: no type named 'type' in 'A'
requires has_type<Traits> && std::same_as<Type, typename Traits::type>
Full example.
Questions
What is the idiomatic way to define set depending on whether Traits class contains type?
Why does clang try to evaluate std::same_as if requires has_type failed?
Who is right, clang or gcc?
A class template member function is constrainable, but is not SFINAE-aware. The idiomatic solution (which, inter alia, works even under C++17) is to make set a (class template member) function template accessing the type member type alias via (type-dependent) SFINAE context:
template<int..., class U = Traits>
void set(typename U::type);
or:
template<std::same_as<Traits> U = Traits>
void set(typename U::type);
Example.
wrt 2., 3., see How to use a trait type as an argument to an optionally compiled member function of a class template?
Looks like I am doing a basic mistake here. I have a 3 party C++ library(test.dll) in which there is a API defined as follows. And I am invoking this APi by loading the library, getting the API and invoke. I am new to C++ CLI, any pointers to solve the issue will be helpful. Thanks in advance.
3rd part library exported API
FUNCTION_EXPORT void STDCALL GetVersion(UINT16& version);
typedef void (STDCALL *GETVERSION)(UINT16);
I need to call it from C++ Cli
Header file
MyTest.h
namespace MyTest {
public ref class TestClass
{
public:
HMODULE module;
String^ version;
void TestMethod()
};
}
Cpp file
MyTest.cpp
namespace MyTest {
TestClass::TestMethod()
{
this->module = LoadLibrary(engineDllPath);
if (!this->module)
{
return String::Format("LoadLibrary failed");
};
// Get engine version
GETVERSION GetVersionApi = (GETVERSION)GetProcAddress(module, "GetVersion");
if (!GetVersionApi)
{
return;
}
UINT16 major;
GetVersionApi(&uiMajor);
}
}
Getting compilation error
error C2664: 'void (UINT16 &)' : cannot convert parameter 1 from 'UINT16 *' to 'UINT16 &'
Code snippet is to give an idea what I am trying. The main issue is here
UINT16 major;
GetVersionApi(&uiMajor);
what will be the correct way of calling it. Please help.
GetVersion(UINT16& version);
That's not an integer pointer, that's an integer reference. You don't need to type any extra characters to pass a reference.
GetVersionApi(uiMajor);
// ^ no "&"
I tried to declare the following in my C++/CLI code.
public ref class MyClass
{
public:
const String ^MyLuckyNumber = "One";
It fails misirably during the compile phase. But in C# the following works.
public class MyClass
{
public const string NowMyLuckyNumber = "Two";
How can I declare a 'const String^' in C++/CLI?
I tried to google on it but no luck!
I believe the keyword you're looking for is literal
literal String ^MyLuckyNumber = "One";
the literal keyword implies a static const on the variable you're declaring. Also, the keyword requires an initialization during the declaration, something you'd expect from a static const declaration.
MSDN Reference
I want to change the global variable in a function where a local variable of same is already present.
int x=10; //global variable
void fun1()
{
fun2(5);
}
void fun2(int x)
{
x=7; //here i want that this statement assigns the value 7 to the global x
}
Just qualify it with this. It's a pretty common pattern, particularly for constructors:
public class Player
{
private readonly string name;
public Player(string name)
{
this.name = name;
}
}
While I view it as acceptable if your parameter really is meant to be a new value for the field (potentially in a method which creates a new instance based on the current one and the new value for the single field, for example), I would try to avoid it in general, just from a readability perspective. Of course, the names of your private fields are an implementation detail, but when reading the code for the method, it's confusing to have two different concepts represented by the same variable name.
Rename the local parameter value.
Like Yuriy Vikulov said.
this.x for non-static variables
int x=10; //global variable
void fun1()
{
fun2(5);
}
void fun2(int lx)
{
x=7; //if you want 7
x=lx; //if you want the paramValue
}
this.x for non-static classes
NameClass.x for static variables
I tried making an extension to the built-in String class using C++/CLI, and using it from C++/CLI without success.
Here's the simplest I can boil it down to:
[System::Runtime::CompilerServices::Extension]
public ref class MyStringExtensions abstract sealed {
public:
[System::Runtime::CompilerServices::Extension]
static bool TestMethod(System::String^ str) { return false; }
};
Now, when I try to use this in other C++/CLI code, I get a compiler message indicating that TestMethod is not a method of String.
String^ foo = gcnew ...
...
blah = foo->TestMethod(); // compile-error
Any ideas?
C++ doesn't have extension methods.
But it does have ADL (Argument-dependent lookup, also known as Koenig lookup) which is arguably even nicer.