Wie kann man einen C ++ - Vorlagenausdruck funktionieren?C++

Programme in C++. Entwicklerforum
Guest
 Wie kann man einen C ++ - Vorlagenausdruck funktionieren?

Post by Guest »

Ich verwende den Vorlagenausdruck über eine benutzerdefinierte Klasse und weiß nicht, wie der Operator+ funktioniert. Das folgende Beispiel wird aus dem ursprünglichen Code vereinfacht, der darauf abzielt, meinen eigenen ganzzahligen Typ mit Expressionsvorlage zu verwenden, wobei INT -Instanzen im Ausdrucksvorlagenbaum gehalten werden. : < /p>

Code: Select all

#include 

template 
class IntExpr
{
public:
//typedef typename E::Type Type; //KO

static constexpr bool is_leaf = false;

template 
T number() const
{
return static_cast(*this).number();
}

template 
IntExpr& operator+=(T const& other)
{
*this = *this + other;

return *this;
}
};

template 
class IntAdd : public IntExpr
{
typename std::conditional::type u_;
typename std::conditional::type v_;

public:
static constexpr bool is_leaf = false;

IntAdd(E1 const& u, E2 const& v) : u_(u), v_(v)
{
}
};

template 
class Int : public IntExpr
{
public:
typedef T Type;

static constexpr bool is_leaf = true;

template 
Int(IntExpr const& expr)
{
number_ = expr.number();
}

explicit Int(int number) : number_{number}
{

}

T number() const
{
return number_;
}

Int& operator+=(Int const& other)
{
number_ += other.number_;

return *this;
}

private:
T number_;
};

template 
inline IntAdd operator+(IntExpr const& u, IntExpr const& v)
{
return IntAdd(*static_cast(&u), *static_cast(&v));
}
template * = nullptr>
inline decltype(auto) operator+(IntExpr const& lhs, S const& rhs)
{
//return lhs + Int(rhs); //KO
return lhs + T(rhs);
}

template * = nullptr>
inline decltype(auto) operator+(S const& lhs, IntExpr const& rhs)
{
//return rhs + Int(lhs); //KO
return rhs + T(lhs);
}

int main()
{
auto const a((Int(1) + 2) + 3);
auto const b((Int(1) + 2) + 3);

return 0;
}
Der vollständige Fehler ist (da int keine Int-Instanz ist):

Code: Select all

D:\programmation\cpp\TestTemplateExpression\main.cpp: In instantiation of 'decltype(auto) operator+(const IntExpr&, const S&) [with T = IntAdd; S = int; std::enable_if_t*  = 0]':
D:\programmation\cpp\TestTemplateExpression\main.cpp:96:38:   required from here
D:\programmation\cpp\TestTemplateExpression\main.cpp:84:18: error: no matching function for call to 'IntAdd::IntAdd(const int&)'
84 |     return lhs + T(rhs);
|                  ^~~~~~
D:\programmation\cpp\TestTemplateExpression\main.cpp:34:9: note: candidate: 'IntAdd::IntAdd(const E1&, const E2&) [with E1 = Int; E2 = Int]'
34 |         IntAdd(E1 const& u, E2 const& v) : u_(u), v_(v)
|         ^~~~~~
D:\programmation\cpp\TestTemplateExpression\main.cpp:34:9: note:   candidate expects 2 arguments, 1 provided
D:\programmation\cpp\TestTemplateExpression\main.cpp:26:7: note: candidate: 'constexpr IntAdd::IntAdd(const IntAdd&)'
26 | class IntAdd : public IntExpr
|       ^~~~~~
D:\programmation\cpp\TestTemplateExpression\main.cpp:26:7: note:   no known conversion for argument 1 from 'const int' to 'const IntAdd&'
D:\programmation\cpp\TestTemplateExpression\main.cpp:26:7: note: candidate: 'constexpr IntAdd::IntAdd(IntAdd&&)'
D:\programmation\cpp\TestTemplateExpression\main.cpp:26:7: note:   no known conversion for argument 1 from 'const int' to 'IntAdd&&'
Um int in eine Int-Instanz zu konvertieren, habe ich versucht, eine Typedef (kommentierte Zeilen) zu verwenden, aber die Definition der Klasse ist zu diesem Zeitpunkt noch nicht vollständig.

Code: Select all

:\programmation\cpp\TestTemplateExpression\main.cpp: In instantiation of 'class IntExpr':
D:\programmation\cpp\TestTemplateExpression\main.cpp:41:7:   required from 'class Int'
D:\programmation\cpp\TestTemplateExpression\main.cpp:96:29:   required from here
D:\programmation\cpp\TestTemplateExpression\main.cpp:7:34: error: invalid use of incomplete type 'class Int'
7 |         typedef typename E::Type Type; //KO
|                                  ^~~~
D:\programmation\cpp\TestTemplateExpression\main.cpp:41:7: note: declaration of 'class Int'
41 | class Int : public IntExpr
|       ^~~
< /code>
Gibt es einen Trick, um dieses Problem zu lösen? Vielleicht verwenden Sie STD :: Bedingung mit Rekursion, wenn intExpr auf Leafs wahr ist, aber ich weiß nicht wie. 
Mit anderen Worten, wenn ich die Situation gut verstehe:  < Br />template 
constexpr inline decltype(auto) operator+(IntExpr const& u, T const& v)
{
//How to scan E to get S that IntType=Int;

return IntAdd(*static_cast(&u), IntType(v));
}
Eine Problemumgehung kann darin bestehen, den S-Typ (z. B. mit char) wie folgt zu korrigieren:

Code: Select all

#include 
#include 

template 
class IntExpr
{
public:
static constexpr bool is_leaf = false;

constexpr decltype(auto) number() const
{
return static_cast(*this).number();
}
};

template 
class IntAdd : public IntExpr
{
public:
constexpr IntAdd(E1 const& u, E2 const& v) : u_(u), v_(v)
{
}

constexpr decltype(auto) number() const
{
return u_.number() + v_.number();
}

private:
typename std::conditional_t u_;
typename std::conditional_t v_;
};

template 
class Int : public IntExpr
{
public:
static constexpr bool is_leaf = true;

template 
constexpr Int(IntExpr const& expr)
{
number_ = expr.number();
}

template 
constexpr Int(S const& number) : number_(static_cast(number))
{
}

constexpr T const& number() const
{
return number_;
}

private:
T number_{0};
};

template 
constexpr inline IntAdd operator+(IntExpr const& u, IntExpr const& v)
{
return IntAdd(*static_cast(&u), *static_cast(&v));
}

template 
constexpr inline decltype(auto) operator+(IntExpr const& u, T const& v)
{
return IntAdd(*static_cast(&u), Int(v));
}

template 
constexpr inline decltype(auto) operator+(T const& u, IntExpr const& v)
{
return IntAdd(Int(u), *static_cast(&v));
}

int main()
{
auto const a(Int(1));
auto const b(Int(1) + 2);
auto const c((Int(1) + 2) + 3);

std::cout

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post