mercredi 2 février 2022

C++ call to list constructor is ambiguous

I'm trying to build an old C++ project on a modern version of Clang and getting lots of ambiguous errors. I don't have much C++ experience so apologies if this is basic stuff.

/home/ubuntu/NameAndTypeResolver.cpp:124:40: error: call to constructor of 'list<list<const dev::libcrunch::ContractDefinition *> >' is ambiguous
        list<list<ContractDefinition const*>> input(1, {});
                                              ^     ~~~~~

I'm not sure what the compilers asking for here. Additionally what is the {} syntax?

Raw pointer but modern way

I have to have a semantic stack in my project which is going to hold multiple types in it.
I aim to have my project to use modern C++.
What is the correct way to have a stack of any type ?
Equivalent version in java is Stack<Object>.
Which of these are correct?

  1. Use void* and cast it to the type I want.
  2. Something as 1 but using some smart pointers. (I don't know what)

C++ program where user will input names and decide which gender (M/F) to show

Using c++ I need to make a program using map in c++ where the gender (M or F) is the key of 6 input names, and then it will ask the user to choose what gender to display (Male or Female). I am stuck with this, I do not know what to do next.

#include <iostream>
#include <map>
using namespace std;

int main()
{
    map<char,string> mapName;
    map<char,string>::iterator mapITR;

    cout<<"Enter 6 names: "<<endl;
    for(int a=1; a<=6; a++){
        
        
    }

    return 0;
}

How to properly destroy a UDP Socket in QT?

I'm working with QT UDP Sockets. This Socket are part of a "communication" class called, say, Com. It happens, for the needs of my application, that Com need to be deleted. Now, my question is: is it sufficient to invoke delete myUdpSocket; or should I explicitly invoke flush(), 'close()` or whatever? I ask this because when I delete Com the application does not necessairly need to close but instead it it possible that a new Instance of om need to be instantiated and with that a new instance of a UDP Socket on the same port and at the same addresses.

mardi 1 février 2022

why can't add Specialization template in this case

when I add MYClass Specialization template , in this case, it will come out compile error, like this:

pet@iZbp1aq6c9kbbder4q405mZ:~/template_class/template_demo/2part/2_7$ g++ main.cpp  test.cpp
/usr/bin/ld: /tmp/ccRiDoql.o: in function `MYClass<int>::func()':
test.cpp:(.text+0x0): multiple definition of `MYClass<int>::func()'; /tmp/ccvTW7yj.o:main.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

I can't find the reason. In this case, I add MYClass Specialization template, it also cause compile failed.I dont' know why. the details code is below like this: template.h

#ifndef __MYCLASS_H__
#define __MYCLASS_H__

#include <iostream>

template <typename T>
class MYClass
{
public:
    void func();
};

template <typename T>
void MYClass<T>::func()
{
    std::cout << "MYClass::func!" << std::endl;
}


template <>
class MYClass<int>
{
public:
    void func();
};


void MYClass<int>::func()
{
    std::cout << "MYClass<int>::func!" << std::endl;
}

template <typename T>
void myfunc(T v1, T v2)
{
    std::cout << v1 + v2 << std::endl;
}
#endif

test.cpp

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

using namespace std;

template class  MYClass<float>; 
template void myfunc(int v1, int v2); 

void funcTest()
{
    MYClass<float> a;
    a.func();
}

main.cpp

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

using namespace std;

extern template class  MYClass<float>; 
extern template void myfunc(int v1, int v2); 
int main()
{

    MYClass<float> mycls;
    mycls.func();
    myfunc<int>(1,2);
    return 0;

}

I can't understand,why can't add this into here, when it removed, compile passed

template <>
class MYClass<int>
{
public:
    void func();
};


void MYClass<int>::func()
{
    std::cout << "MYClass<int>::func!" << std::endl;
}

Call different initializer after type checking

I have a generic class, where two of the generics are going to be identical 90% of the time, but on the off chance that they are separate types, I need to perform member initialization a little bit differently.

template<typename S, typename T = S>
class MyClass {
    MyClass(const Options<S> & opts) {
        if (std::is_same<S,T>::value) {
            thing.reset(new T(opts.get_s_thing()));   // 90% of time, use type S in args to initialize thing
        } else {
            thing.reset(new T());              // Special case, types differ, so create a new one
        }
        //
        // Other constructor things...
        //
    }

    std::shared_ptr<T> thing;
};

Only thing is, since type-checking is done at compile time, the thing.reset(opts.get_s_thing()); line throws an error if I create MyClass with an explicitly different type for T. But because the types differ, that line would never get called anyways. Is there some preprocessor directive I can use here? What strategy should I take?

Changing the constructor signature in MyClass is not an option, since this is part of a VERY large codebase. T is a new thing, so I have more freedom in deciding the "standard interface" for Ts.

Correctly move from a data member of a temporary object

Consider the following C++-Code

#include <iostream>
using namespace std;

struct WrapMe
{
    WrapMe() { cout << "WrapMe Default Ctor of: " << this << endl; }
    WrapMe(const WrapMe& other) { cout << "WrapMe Copy Ctor of " << this << " from " << &other << endl; }
    WrapMe(WrapMe&& other) noexcept { cout << "WrapMe Move Ctor of " << this << " from " << &other << endl; }
    ~WrapMe() { cout << "Wrap Me Dtor of" << this << endl; }
};


struct Wrapper1
{
    WrapMe& data()& { return member; }
    WrapMe data()&& { return std::move(member); }

    WrapMe member;
};

struct Wrapper2
{
    WrapMe& data()& { return member; }
    WrapMe&& data()&& { return std::move(member); }

    WrapMe member;
};

int main()
{
    auto wrapMe1 = Wrapper1().data();
    auto wrapMe2 = Wrapper2().data();
}

with the output

WrapMe Default Ctor of: 00000092E7F2F8C4
WrapMe Move Ctor of 00000092E7F2F7C4 from 00000092E7F2F8C4
Wrap Me Dtor of00000092E7F2F8C4
WrapMe Default Ctor of: 00000092E7F2F8E4
WrapMe Move Ctor of 00000092E7F2F7E4 from 00000092E7F2F8E4
Wrap Me Dtor of00000092E7F2F8E4
[...]

Which is the correct way to move from the WrapMe member: Like Wrapper1 (return by value) or like Wrapper2 (return by rvalue-reference) does? Or are both ways equivalent here, as the ouput suggests? If not, why?