In Solidity Language, what happens when a function with given parameters on different contracts but different types of data stored for Interface? - interface

For Solidity Programing Language,
While defining Interface, we name it as per our needs and then call it as needed with the same types of inputs.
What happens when there are the same function names with the same parameter names but different types of data stored?
Eg. Here are two different contracts stored on Ethereum Blockchain separately. What will happen if while writing a 3rd smart contract, I create an interface and call function with name "favoriteNumber". Which value will it return? 10 or 15?
contract A {
uint randomnumber = 10;
function favoriteNumber (uint _number) public view returns(uint randomnumber) {
}
}
contract B {
uint randomnumber = 15;
function favoriteNumber (uint _number) public view returns(uint randomnumber) {
}
}

It will depends on what contract you call, each contract have it unique address with each own storage

Related

TypeError: Type bytes4 is not implicitly convertible to expected type bytes memory

Please help I am quite confused since I was following a course online and i've double checked everything I can and compare his code to mine yet I have an error and he doesn't. please help. :)
pragma solidity ^0.8.7;
interface IERC165 {
// this is an interface because we have statically declared it as an interface.
// and it contains only unimplemented functions.
// what is the calculation for this function supportsInterface:
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
contract ERC165 is IERC165 {
// write a calculation interface function algorithm
function calcFingerPrint() public view returns(bytes4) {
return bytes4(keccak256('supportedInterface(bytes4)'));
}
// hash table to keep track of contract fingerprint data of byte function covers
mapping(bytes => bool) private _supportedInterfaces;
function supportsInterface(bytes4 interfaceId) external override view returns (bool) {
_supportedInterfaces[interfaceId];
}
/*
The ERC165 standard actually requires that the supportsInterface function "use less than 30,000 gas"
So rather than re-calculating interfaceIDs every time someone cals supportsInterface, lets keep our
supported interfaceID in a mapping.
bytes4 Bytes is dynamic array of bytes. It's shortened for byte[]
bytes4 is exactly 4 bytes long.
You can define a available by using the keyword bytesX where X represents
the sequence of bytes. X can be from 1 up to 32
keccak26: keccak256 compute the keccak-256 hash of the input. Creating a deterministic unique ID from an input.
*/
} ```
This line causing issue
mapping(bytes => bool) private _supportedInterfaces;
You defined your mapping bytes=>bool.
mapping(bytes4 => bool) private _supportedInterfaces;

C++11: How to create an enum class inside an class that behaves like a sub class?

To explain my problem I posted an example below. The code in this form is not tested so there might be some syntax mistake in it. As I have to work with a lot of registers in an integrated circuit with their addresses which can be remapped, it would be very useful to create structures like that below. Is there some trick to create these structures? As this example does not work the way I want it because foo requires a Country object and Country::Europe::Italy is invalid as parameter.
// I want to create a structure like this
class myClass {
public:
class Country {
enum class Europe {
England,
France,
Germany,
Italy
};
enum class Asia {
China,
Japan
};
};
// Here I want to make sure, that the method is only
// called with a Country element and e.g. Italy should
// behave like a Country object. Actually it should behave
// as if it is derived from Country.
int foo(Country c);
};
int main() {
myClass myC();
// Exemplary call of the method foo
myC.foo(myClass::Country::Europe::Italy);
}
You cannot use enum class to achieve your goal. However, you can use a namespace with a set of hardcoded constexpr objects:
struct Country
{
int _id;
};
namespace Countries
{
namespace Europe
{
constexpr Country Italy{0};
constexpr Country France{1};
};
};
Usage:
myC.foo(Countries::Europe::Italy);
A proper example using registers and a better explanation would have been better. I guess you want to remap from one register name to another. A suggestion:
class Register {
public:
enum class UserName {
REG_IO0,
REG_MEM1
};
enum class CPUName {
REG_INT0,
REG_INT1
};
void setMapping(UserName from, CPUName to); // store the mapping
CPUName getMapping(UserName name) const; // retrieve the mapping
private:
std::map<UserName, CPUName> m_registerMap;
};
If you want you could implement get/set methods for the registers in that class if you store the indexes/adresses of the registers. Either use templates or overload them for different data types.
You can explicitly use an enum type as a function or constructor argument, restricting the caller to using that enumeration.
The thing you can't trivially do is combine multiple enum definitions in the way that you have suggested.
You could write several constructors, one for each of the enums Europe, Asia, etc, but that would be work, especially if you have a number of functions that need to take these enums as arguments.
--OR--
You could define one big enum, and define fixed value separators for each subgroup, so you can compare the enum value against these guard values to identify the subgroup. You lose the sub-grouping if you do that. You could use c++11 constant enum initialisers to construct enum value members in subclasses for each continent - but note these are only available for enum class from c++17 (so I am using a nested class trick to provide the member namespace enforcement - in c++17 you could have enum class Location - you can write this in c++11 but you can't then do the const initialisers). The values follow the above rule of separators, but callers have to indirect through the subclasses to get the names.
class Country
{
class Location {
enum Value {
None =0,
Europe = 0x0100,
Asia = 0x0200,
//etc
};
};
struct Asia {
const Location::Value Japan { Location::Asia + 1 };
//etc
};
struct Europe {
const Location::Value UnitedKingdom { Location::Europe + 1 };
//etc
};
// etc
};
Then you could have
class myClass {
public:
myClass(Country::Location::Value v);
};
And call it with
myClass instance(Country::Asia::Japan);
-- OR --
You could define another structure who's only purpose is to take the various enumerations and convert them to a pair of values for the continent and country index. You could then use that structure as your function parameter, and allow auto-conversion from that structure. This means you only do the conversion once, and callers to your code are not impacted. You could use the guard ranges such that you don't need to explicitly store the continent code, just the raw country number would be unique across all your enums.

Protobuf without serialization

As the name suggests I was wondering if it makes sense to use Protobuf without the requirement of having to serialize the data in any form at the moment (might change in future). I mean to use them purely as data structures to pass Information from one function to the other, all executed in the same address space. Or do you feel it may be an Overkill and see other alternatives.
Backgroud:
I have to design a lib that implements certain interfaces. At the moment, my collegues have implemented it using several functions taking arguments ..
Example:
void readA(int iIP1, int iIP2, Result& oOP)
void readB(std::string iIP1, Result& oOP)
void readC(std::vector<int> iIP1, Result& oOP)
I want to change this and provide just one interface function:
void ReadFn(ReadMsg& ip, ReadResult& res);
And the data structures are defined in Protobuf as below ..
message ReadMsg {
enum ReadWhat {
A = 0;
B = 1;
C = 2;
}
message readA {
int32 iIP1 = 1;
int32 iIP2 = 2;
}
message readB {
string IP1 = 1;
}
message readC {
repeated int IP1 = 1;
}
oneof actRead {
readA rA = 1;
readB rB = 2;
readC rC = 3;
}
}
It offers many advantages over traditional interface design(using functions), with very Little effort from my side. And it will be future proof should these components be deployed as Services in different processes/machines (ofcourse with additional implementation). But given that Protocol Buffers strength is their serialization Features, which I do not make use of at the moment, would you choose to use them in such trivial Tasks ?
Thank you
It can make sense to group function arguments into a struct if there are many of them. And it can make sense to combine your readA, readB and readC functions into a single function if they share a lot of common parts.
What doesn't, however, make sense in my opinion is introducing a separate .proto file and a protobuf dependency if you are not going to use it for serialization. Similar features for grouping data into reusable structures already exist in most languages. And when you use the built-in features of the language, all the code remains in the same place and is easier to understand.

Is it possible to use template arguments in virtual function in modern C++?

I used to do C++ development several years ago and back then I found it difficult to combine template programming with OOP. Currently I program in Swift and I tried doing some of the things I struggled with then.
This Swift code will illustrate the problem:
// protocol is like Java interface or C++ pure virtual base class
protocol Log {
// want to able to add elements from a collection of Ints, but
// it should be any sort of collection that
// can be treated as a sequence
func add<T: SequenceType where T.Generator.Element == Int>(values: T)
}
class DiscreteLog: Log {
var vals: [Int] = []
func add<T: SequenceType where T.Generator.Element == Int>(values: T) {
for v in values {
vals.append(v)
}
}
}
class ContinousLog: Log {
var vals: [Double] = []
func add<T: SequenceType where T.Generator.Element == Int>(values: T) {
for v in values {
vals.append(Double(v))
}
}
}
// I don't have to know whether the log is Continuous or Discrete
// I can still add elements to it
var log: Log = ContinousLog()
log.add([1, 2, 3])
// and elements can come from any kind of sequence, it does not need
// to be an array
log.add(["four": 4, "five: 5].values)
So the problem is that if the C++ code defined as as:
virtual void add(vector<Int> elements>)
Then sure I could have multiple subclasses implement this method, but I could never provide anything but vectors as arguments.
I could try changing it to something more generic using iterator:
virtual void add(vector<Int>::iterator elements>)
But I am still limited to using vector iterators. So I guess I would have to write something like:
template<typename Iterator>
virtual void add(Iterator elements>)
But that will give compile errors as template based arguments are not allowed for virtual methods.
Anyway I wondered if this sort of thing is possible in modern C++.
C++ templates and C#/Swift/Java generics are different things.
They are both "pattern code" in a sense (they are patterns that generate code), but C#/Swift/Java generics use type erasure and "forget" almost everything about the types they work with, while C++ templates are elephants. And elephants never forget.
It turns out that can make an elephant forget, but you have to tell it to. The technique of "forgetting" about details of a type is known as "type erasure" or "run time concepts".
So you want to type erase down to the concept of "a sequence of integers". You want to take any type, so long as it is a sequence of integers, and be able to iterate over it. Seems fair.
boost has such type erasures. But who wants to always rely on boost?
First, type erase an input iterator:
template<class T>
struct input_iterator:
std::iterator<
std::input_iterator_tag, // category
T, // value
std::ptrdiff_t, // distance
T*, // pointer
T // reference
>
{
struct erase {
virtual void advance() = 0;
virtual erase* clone() const = 0;
virtual T get() const = 0;
virtual bool equal(erase const& o) = 0;
virtual ~erase() {}
};
std::unique_ptr<erase> pimpl;
input_iterator(input_iterator&&)=default;
input_iterator& operator=(input_iterator&&)=default;
input_iterator()=default;
input_iterator& operator++() {
pimpl->advance();
return *this;
}
input_iterator operator++(int) {
auto copy = *this;
++*this;
return copy;
}
input_iterator(input_iterator const& o):
pimpl(o.pimpl?o.pimpl->clone():nullptr)
{}
input_iterator& operator=(input_iterator const&o) {
if (!o.pimpl) {
if (pimpl) pimpl->reset();
return *this;
}
pimpl = std::unique_ptr<erase>(o.pimpl->clone());
return *this;
}
T operator*() const {
return pimpl->get();
}
friend bool operator==( input_iterator const& lhs, input_iterator const& rhs ) {
return lhs.pimpl->equal(*rhs.pimpl);
}
friend bool operator!=( input_iterator const& lhs, input_iterator const& rhs ) {
return !(lhs==rhs);
}
template<class It>
struct impl:erase{
It it;
impl(impl const&)=default;
impl(It in):it(std::move(in)){}
virtual void advance() override { ++it; }
virtual erase* clone() const override { return new impl(*this); }
virtual T get() const override { return *it; }
virtual bool equal(erase const& o) override {
return static_cast<impl const&>(o).it == it;
}
};
template<
class It,
class=std::enable_if<
std::is_convertible<
typename std::iterator_traits<It>::reference,
T
>{}
>
>
input_iterator(It it):pimpl( new impl<It>{it} ) {}
}; // input_iterator
Next, have a range template. This is a container that stores non-type erased iterators, and exposes enough to iterate over those iterators.
template<class It>
struct range {
It b; It e;
It begin() const { return b; }
It end() const { return e; }
range() = default;
range(It start, It finish):b(std::move(start)),e(std::move(finish)) {};
range(range&&)=default;
range(range const&)=default;
range& operator=(range&&)=default;
range& operator=(range const&)=default;
template<class R,
class R_It=std::decay_t<decltype(std::begin(std::declval<R>()))>,
class=std::enable_if< std::is_convertible<R_It, It>{} >
>
range( R&& r ):
range(std::begin(r), std::end(r))
{} // TODO: enable ADL begin lookup
};
The above type is really basic: C++1z has better ones, as does boost, as do I have in my own code base. But it is enough to handle for(:) loops, and implicit conversion from containers with compatible iterators.
Finally our sequence type:
template<class T>
using sequence_of = range<input_iterator<T>>;
Wait, that's it? Nice, those types compose well!
And barring errors, we are done.
Your code now would take a sequence_of<int>, and they could pass a std::vector<int> or std::list<int> or whatever.
The input_iterator type-erasure type-erases any iterator down to getting a T via *, ==, copy, and ++ advance, which is enough for a for(:) loop.
The range<input_iterator<int>> will accept any iterable range (including containers) whose iterators can be converted to an input_iterator<int>.
The downside? We just introduced a bunch of overhead. Each method goes through virtual dispatch, from ++ to * to ==.
This is (roughly) what generics do -- they type-erase down to the requirements you give it in the generic clause. This means they are working with abstract objects, not concrete objects, so they unavoidably suffer performance penalties of this indirection.
C++ templates can be used to generate type erasure, and there are even tools (boost has some) to make it easier. What I did above is a half-assed manual one. Similar techniques are used in std::function<R(Args...)>, which type-erases down to (conceptually) {copy, call with (Args...) returning R, destroy} (plus some incidentals).
live example.
(The code above freely uses C++14.)
So the C++ equivalent Log is:
struct Log {
virtual void add(sequence_of<int>) = 0;
virtual ~Log() {}
};
Now, the type erasure code above is a bit ugly. To be fair, I just implemented a language feature in C++ without direct language support for it.
I've seen some proposals to make type erasure easier in C++. I do not know the status of those proposals.
If you want to do your own, here is an "easy" way to do type erasure in 3 steps:
First, determine what operations you want to erase. Write the equivalent of input_iterator<T> -- give it a bunch of methods and operators that do what you want. Be sparse. Call this the "external type". Ideally nothing in this type is virtual, and it should be a Regular or Semi-regular type (ie, it should behave value-like, or move-only-value-like). Don't implement anything but the interface yet.
Second, write an inner class erase. It provides a pure-virtual interface to a set of functions that could provide what you need in your external type.
Store a unique_ptr<erase> pimpl; within the external type. Forward the methods you expose in the external type to the pimpl;.
Third, write an inner template<class X> class impl<X>:erase. It stores a variable X x;, and it implements everything in erase by interacting with X. It should be constructable from an X (with optional perfect forwarding).
You then create a perfect forwarding constructor for the external type that creates its pimpl via a new impl<X>(whatever). Ideally it should check that its argument is a valid one via SFINAE techniques, but that is just a qualify of implementation issue.
Now the external type "erases" the type of any object it is constructed from "down to" the operations you exposed.
Now, for your actual problem, I'd write array_view or steal std::experimental::array_view, and restrict my input to be any kind of contiguous buffer of data of that type. This is more performant, and accepting any sequence is over engineering unless you really need it.

Using Matlab Compiler SDK: Sharing data in same class

I'm looking to create a .NET application which calls various matlab functions to process some data. What I want to do is have a single class where multiple functions can access the same variables. Below is some pseudocode of what I would like to do. I want to call one function that sets a variable, and another function that returns the value of the variable.
class TestClass
{
int x;
public void SetX(int new_x)
{
x = new_x;
}
public int GetX()
{
return x;
}
}
Using Matlab Compiler SDK, I know that I can call individual functions, but is there a way multiple functions will be able to interact with the same variable like the above functions?