I'm reading C++/CLI. I see this stuff:
Object^ CreateInstanceFromTypename(String^ type, ...array<Object^>^ args)
{
if (!type)
throw gcnew ArgumentNullException("type");
Type^ t = Type::GetType(type);
if (!t)
throw gcnew ArgumentException("Invalid type name");
Object^ obj = Activator::CreateInstance(t, args);
return obj;
}
When calling it:
Object^ o = CreateInstanceFromTypename(
"System.Uri, System, Version=2.0.0.0, "
"Culture=neutral, PublicKeyToken=b77a5c561934e089",
"http://www.heege.net"
);
What is ...array^ args? If I remove ... ,there's a complied-error:
error C2665: 'CreateInstanceFromTypeName' : none of the 2 overloads could convert all the argument types
1> .\myFourthCPlus.cpp(12): could be 'System::Object ^CreateInstanceFromTypeName(System::String ^,cli::array<Type> ^)'
1> with
1> [
1> Type=System::Object ^
1> ]
1> while trying to match the argument list '(const char [86], const char [21])'
Like C++, C++/CLI has a mechanism for a variable amount of arguments. That is what the ... in front of the ...array<Object^>^ parameter means.
For type safety the C++/CLI designers added managed syntax to declare the type of the variable array.
Since it's just passing that parameter to the Activator::CreateInstance() function, I would look at what variable parameters the Activator function is looking for.
Related
Consider the following function:
#include <utility>
#include <iterator>
#include <algorithm>
template<template<class, class> class Map, typename Key, typename Value , typename F>
auto transform_values(const Map<Key,Value>& map, const F& value_mapper)
{
using mapped_value_type = decltype(value_mapper(std::declval<Value>()));
Map<Key, mapped_value_type> transformed;
std::transform(map.cbegin(), map.cend(), std::inserter(transformed, transformed.begin()),
[&value_mapper](const auto& pair) {
const auto& key = pair.first;
const auto& value = pair.second;
return {key, value_mapper(value)};
}
);
return transformed;
}
g++ 12 accepts this, clang++ 14 does not (GodBolt). clang++ 14 says:
<source>:15:20: error: cannot deduce lambda return type from initializer list
return {key, value_mapper(value)};
^~~~~~~~~~~~~~~~~~~~~~~~~~
Why won't it deduce the lambda's type?
I can't see how the compiler can deduce return type here. The return type of the lambda should be convertible to the type pointed to by the output iterator, but without complete container class it doesn't even know what this type is.
Edit.
For the part what rule makes it fail (i.e. why no valid specialization can be generated), i believe it refers to 9.2.9.6.2 Placeholder type deduction / 2.1.2 rule:
A type T containing a placeholder type, and a corresponding initializer-
clause E, are determined as follows:
For a non-discarded return statement that occurs in a function declared with a return type that contains a placeholder type, T is the declared return type.
...
If the operand is a braced-init-list ([dcl.init.list]), the program is ill-formed.
Paraphrasing here, but this is the problem
xt::pyarray< std::complex<double> > output;
output = 0; // fails to compile
output = double(0); // also fails to compile
output = complex<double>(0); // succeeds
and yet this is fine
std::complex<double> foo;
foo = double(0);
The problem is I'm writing a function which accepts arbitrary xtensor array, eg.
template<typename xtarray_t>
void my_function(xtarray_t &output, const xtarray_t &input) {
output = 0;
}
so in general this
output = complex<double>(0);
would fail. I've seen this, but am not sure if this was implemented, or how to use it, couldn't find the documentation. In general though, I think it should still work with std::complex.
thanks for any help!
compiler output:
xtensor-python/include/xtensor-python/pyarray.hpp:360:20: note: candidate function not viable: no known conversion from 'double' to 'const xt::pyarray<std::__1::complex<double>, xt::layout_type::dynamic>::self_type' (aka 'const pyarray<std::__1::complex<double>, (xt::layout_type)0>') for 1st argument
self_type& operator=(const self_type& rhs);
xtensor-python/include/xtensor-python/pyarray.hpp:363:20: note: candidate function not viable: no known conversion from 'double' to 'xt::pyarray<std::__1::complex<double>, xt::layout_type::dynamic>::self_type' (aka 'pyarray<std::__1::complex<double>, (xt::layout_type)0>') for 1st argument
self_type& operator=(self_type&& e) = default;
xtensor-python/include/xtensor-python/pyarray.hpp:369:20: note: candidate template ignored: could not match 'xexpression<type-parameter-0-0>' against 'double'
self_type& operator=(const xexpression<E>& e);
Answer is to do this
using value_t = typename xtarray_t::value_type;
output = value_t(0);
i need to fill a collection with another list in c++/cli so the problem that when i try to do that i got an error
error C2664: 'SpaceClaim::Api::V10::InteractionContext::Selection::set' : cannot convert parameter 1 from 'System::Collections::Generic::ICollection ^' to 'System::Collections::Generic::ICollection ^'
and here the code
List<DesignEdge^> ^newEdges = gcnew List<DesignEdge^>();
for each (DesignEdge^edge in onecopiedBody->Edges)
{
if (!edges->Contains(edge))
{
newEdges->Add(edge);
}
}
cstom->InteractionContext->Selection = safe_cast<ICollection<IDesignEdge^> ^>(newEdges); //error here
The problem is that you're trying to cast from ICollection<DesignEdge^>^ to ICollection<IDesignEdge^>^, which is not safe. What you should do is operate in terms of IDesignEdge from the start:
auto newEdges = gcnew List<IDesignEdge^>();
I am trying to define some custom input types using the new-style YamlCpp API. I have two questions. Let me first say that we are currently using the 0.3 style-api and everything works great. The code-appearance of the new API is about 10x better though so we wanted to move to it.
Why does my current approach bork the compiler?
Is yaml-cpp smart enough to handle nested templates. For example, if my parser knows how to enc/dec std::vectors, and then I define a custom handler for MyAwesomeType separately -- can I ask it to enc/dec a std::vector<MyAwesomeType> and it will figure it out?
My code began by copying and pasting the example on the website (here) and then modifying that. My current implementation attempts to handle conversion of std::vector<std::pair<qint16,qint16>> -- this does not compile. (fyi - qint16 is simply a cross-platform typedef for __int16)
#include "yaml-cpp\yaml.h"
#include <vector>
#include "qglobal.h"
namespace YAML {
// a std::pair of qint16's
template<>
struct convert<std::pair<qint16,qint16>> {
static Node encode( std::pair<qint16,qint16> const& rhs) {
Node node;
std::vector<qint16> newVec;
newVec.push_back(rhs.first);
newVec.push_back(rhs.second);
node = newVec;
return node;
}
static bool decode(Node const& node, std::pair<qint16,qint16> & rhs) {
if(!node.IsSequence() || node.size() != 2) {
return false;
}
rhs.first = node[0].as<qint16>();
rhs.second = node[1].as<qint16>();
return true;
}
};
// a vector of std::pair of qint16's
template<>
struct convert<std::vector<std::pair<qint16,qint16>>> {
static Node encode( std::vector<std::pair<qint16,qint16>> const& rhs) {
Node node;
for(auto pairIt=rhs.begin();pairIt!=rhs.end();++pairIt)
{
node.push_back( *pairIt );
}
return node;
}
static bool decode(Node const& node, std::vector<std::pair<qint16,qint16>> & rhs) {
if( !node.IsSequence() ) {
return false;
}
for(int k=0;k<node.size();++k)
{
rhs.push_back( node[k].as<std::pair<qint16,qint16>>() );
}
return true;
}
};
}
Finally, I would like to then use this to call
std::map<std::string, std::vector<std::pair<qint16, qint16>>> m_vectorOfPairs;
if( doc["myPairs"] )
{
// key exists!
for( YAML::const_iterator it=doc["myPairs"].begin();it!=doc["myPairs"].end();++it)
{
m_vectorOfPairs[it->first.as<std::string>()] = it->second.as<std::vector<std::pair<qint16,qint16>>>();
}
}
...based on input yaml which looks like this...
myPairs:
pairOne: [[4, 25], [48, 336]]
pairTwo: [[4, 25], [57, 336]]
pairThree: [[4, 25], [48, 336]]
The compiler error output from this is about 300 lines, so I will not post that here.
Platform: Visual Studio 2010 SP1 x64
Thanks for your help.
EDIT:
Here is the first of many errors I get, namely that it doesn't even seem happy parsing a Node key with the new style... I'm adding this because what is causing this may be related to the other errors.
Code
YAML::Node doc = YAML::LoadFile(buildFilenamePath(m_spectCameraShortName, relativePath).toStdString());
if( doc["numPixels"] )
//...
Causes
1>ANONPATH\thirdparty\yaml-cpp\include\yaml-cpp/node/detail/impl.h(146): error C2734: 'lhs' : const object must be initialized if not extern
1> ANONPATH\thirdparty\yaml-cpp\include\yaml-cpp/node/detail/impl.h(96) : see reference to function template instantiation 'bool YAML::detail::node_data::equals<const char[10]>(YAML::detail::node &,T (&),YAML::detail::shared_memory_holder)' being compiled
1> with
1> [
1> T=const char [10]
1> ]
1> ANONPATH\thirdparty\yaml-cpp\include\yaml-cpp/node/detail/node_ref.h(52) : see reference to function template instantiation 'YAML::detail::node &YAML::detail::node_data::get<const char[10]>(Key (&),YAML::detail::shared_memory_holder)' being compiled
1> with
1> [
1> Key=const char [10]
1> ]
1> ANONPATH\thirdparty\yaml-cpp\include\yaml-cpp/node/detail/node.h(103) : see reference to function template instantiation 'YAML::detail::node &YAML::detail::node_ref::get<const char[10]>(Key (&),YAML::detail::shared_memory_holder)' being compiled
1> with
1> [
1> Key=const char [10]
1> ]
1> ANONPATH\thirdparty\yaml-cpp\include\yaml-cpp/node/impl.h(333) : see reference to function template instantiation 'YAML::detail::node &YAML::detail::node::get<const char[10]>(Key (&),YAML::detail::shared_memory_holder)' being compiled
1> with
1> [
1> Key=const char [10]
1> ]
1> MYCODEFILE.cpp(75) : see reference to function template instantiation 'YAML::Node YAML::Node::operator []<const char[10]>(Key (&))' being compiled
1> with
1> [
1> Key=const char [10]
1> ]
Note that the Line 75 mentioned in the error above is the
if( doc["numPixels"] )
line
I've recompiled from source latest using Rev 573 of default branch and all these examples are from that code.
Yes, yaml-cpp should be able to handle nested templates (and so you shouldn't need to define a conversion for std::vector<std::pair<qint16, qint16>> - and, this suggests that yaml-cpp should define a conversion for std::pair<T, U> in general (http://code.google.com/p/yaml-cpp/issues/detail?id=188)).
And I'm not sure why the compiler doesn't accept your code (it looks correct, and compiles fine on Linux for me).
Do the tests compile at all? Apparently, 0.5.0 doesn't work out of the box on Visual Studio (see http://code.google.com/p/yaml-cpp/issues/detail?id=182), and I haven't had a chance to test or merge the fix yet.
I am getting familiar with c++/cli. I am writing a function called Locate with a class called Locator. The function that takes input a dictionary of strings.
Dictionary<String^, array< Byte >^>^ Locate(Dictionary<String^, String^>^ imgParms)
I am trying to call it in the main function by doing this:
Locator r;
Dictionary<String^,String^> myDictionary =
gcnew Dictionary<String^,String^>();
r.Locate(myDictionary);
but I am getting this error
error C3073: 'System::Collections::Generic::Dictionary<TKey,TValue>' : ref class does
not have a user-defined copy constructor with
[
TKey=System::String ^,
TValue=System::String ^
]
Any help would be appreciated.
Dictionary<String^,String^> myDictionary =
gcnew Dictionary<String^,String^>();
Should be
Dictionary<String^,String^>^ myDictionary =
gcnew Dictionary<String^,String^>();
the ^ symbol can be thought of as a type modifier like * do gcnew is returning you ax^ to type x