Как заставить выражение выражения шаблона C ++?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как заставить выражение выражения шаблона C ++?

Сообщение Anonymous »

Я использую шаблонное выражение для определяемого пользователем класса и не знаю, как заставить работать оператор+. Следующий пример упрощен по сравнению с исходным кодом, целью которого является использование моего собственного целочисленного типа с шаблоном выражения, содержащего экземпляры Int в дереве шаблонов выражений.
Вот минимальный код, воспроизводящий проблему. :
#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;
}
< /code>
Полная ошибка (потому что int не является экземпляром int): < /p>
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&&'
< /code>
Чтобы преобразовать int в экземпляр Int, я попытался использовать Typedef (комментарии), но определение класса не завершено в данный момент. < /p>
:\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
| ^~~

Есть ли способ решить эту проблему? Возможно, используя std::conditional с рекурсией, если IntExpr на листах, если это правда, но я не знаю, как это сделать.
Другими словами, если я хорошо понимаю ситуацию: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));
}
< /code>
Работа может быть, чтобы исправить тип s (например, char) следующим образом: < /p>
#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:
E1 const u_;
E2 const 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

Подробнее здесь: https://stackoverflow.com/questions/793 ... ssion-work
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»