Я использую шаблонное выражение для определяемого пользователем класса и не знаю, как заставить работать оператор+. Следующий пример упрощен по сравнению с исходным кодом, целью которого является использование моего собственного целочисленного типа с шаблоном выражения, содержащего экземпляры 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
{
const E1 u_;
const E2 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
| ^~~
< /code>
Есть ли трюк, чтобы решить эту проблему? Может использование std :: conditional с рекурсией, если Intexpr на листьях, если это правда, но я не знаю, как.
Другими словами, если я хорошо понимаю ситуацию: < 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));
}
Обходным решением может быть исправление типа S (например, с помощью char) следующим образом:
#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
Как заставить работать выражение шаблона C++? ⇐ C++
Программы на C++. Форум разработчиков
-
Anonymous
1737914858
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
{
const E1 u_;
const E2 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
| ^~~
< /code>
Есть ли трюк, чтобы решить эту проблему? Может использование std :: conditional с рекурсией, если Intexpr на листьях, если это правда, но я не знаю, как.
Другими словами, если я хорошо понимаю ситуацию: < 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));
}
Обходным решением может быть исправление типа S (например, с помощью char) следующим образом:
#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
Подробнее здесь: [url]https://stackoverflow.com/questions/79384205/how-to-make-a-c-template-expression-work[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия