Перечисление шаблона экспрессии приводит к «недействительной арифметике между различными типами перечисления» Intel C ++C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Перечисление шаблона экспрессии приводит к «недействительной арифметике между различными типами перечисления» Intel C ++

Сообщение Anonymous »

Компиляция (решения, содержащего) этого кода в заголовке AAD3.h :

Код: Выделить всё

#include 
#include 

template 
class Expression
{};

/************************************************************************************************************************************************************/
// CRTP (Curiously Recurring Template Pattern)
template 
class ExprTimes : public Expression
{
LHS lhs;
RHS rhs;

public:

// Constructor
explicit ExprTimes
(const Expression& l, const Expression& r)
: lhs(static_cast(l)),
rhs(static_cast(r)) {}

double value() const
{
return lhs.value() * rhs.value();
}

enum { numNumbers = LHS::numNumbers + RHS::numNumbers }; // The line yielding ultimately the error

std::string writeProgram(
// On input, the number of nodes processed so far
// On return the total number of nodes processed on exit
size_t& processed)
{
// Process the left sub-DAG
const std::string ls = lhs.writeProgram(processed);
const size_t ln =
- 1;

// Process the right sub-DAG
const std::string rs = rhs.writeProgram(processed);
const size_t rn = processed - 1;

// Process this node
const std::string thisString = ls + rs +
"y" + std::to_string(processed)
+ " = y" + std::to_string(ln) + " * y" + std::to_string(rn) + "\n";

++processed;

return thisString;
}

// Input: accumulated adjoint for this node or 1 if top node
void pushAdjoint(const double adjoint)
{
lhs.pushAdjoint(adjoint * rhs.value());
rhs.pushAdjoint(adjoint * lhs.value());
}
};

// Operator overload for expressions
template 
inline ExprTimes operator*(
const Expression& lhs, const Expression& rhs)
{
return ExprTimes(lhs, rhs);
}

/************************************************************************************************************************************************************/
template 
class ExprLog : public Expression
{
ARG arg;

public:

// Constructor
explicit ExprLog(const Expression& a)
: arg(static_cast(a)) {}

double value() const
{
return log(arg.value());
}

enum { numNumbers = ARG::numNumbers };

std::string writeProgram(
// On input, the number of nodes processed so far
// On return the total number of nodes processed on exit
size_t& processed)
{
// Process the arg sub-DAG
const std::string s = arg.writeProgram(processed);
const size_t n = processed - 1;

// Process this node
const std::string thisString = s +
"y" + std::to_string(processed)
+ " = log(y" + std::to_string(n) + ")\n";

++processed;

return thisString;
}

// Input: accumulated adjoint for this node or 1 if top node
void pushAdjoint(const double adjoint)
{
arg.pushAdjoint(adjoint / arg.value());
}
};

// Operator overload for expressions
template 
inline ExprLog log(const Expression&  arg)
{
return ExprLog(arg);
}

/************************************************************************************************************************************************************/
// Number type, also an expression
class Number : public Expression
{
double val;
std::shared_ptr adj; // Use a shared pointer so that copies of Number hold the same adjoint value (required to make lines 199 and 200 work)

public:

// Constructor
explicit Number(const double v) : val(v), adj(std::make_shared(0.0)) {} // code modified from text to work with shared pointer

double value() const
{
return val;
}

double adjoint() const
{
return *adj;    // code modified from text to work with shared pointer
}

enum { numNumbers = 1 };

std::string writeProgram(
// On input, the number of nodes processed so far
// On return the total number of nodes processed on exit
size_t& processed)
{
const std::string thisString = "y" + std::to_string(processed) + " = " + std::to_string(val) + "\n";

++processed;

return thisString;
}

void pushAdjoint(const double adjoint)
{
*adj = adjoint;     // code modified from text to work with shared pointer
}
};

/************************************************************************************************************************************************************/
auto calculate(Number t1, Number t2)
{
return t1 * log(t2); // the line triggering the error
}

/************************************************************************************************************************************************************/
template 
constexpr auto countNumbersIn(const Expression&)
{
return E::numNumbers;
}
и следующий код в main.cpp Источник:

Код: Выделить всё

#include "AAD3.h"

int main()
{

Number x1(2.0), x2(3.0);
auto e = calculate(x1, x2);
double e_val = e.value();
int cnt = countNumbersIn(e);
e.pushAdjoint(1.0);
double x1_adj = x1.adjoint();
double x2_adj = x2.adjoint();
}
дает ошибку с помощью платформы с платформой , равным Visual Studio 2022 (v143) , даже со стандартом языка C ++ равен предварительному просмотру - функции из последнего рабочего черновика C ++ (/std: c ++ andal) . Но если я установил платформу инструментов на компилятор Intel C ++ 2025 (или компилятор Intel C ++ 2024 ) с помощью языка C ++ равен предварительному просмотру - Функции из последней рабочей черновики C ++ (/std: c ++ Последний) Компиляция вызывает следующую ошибку:

Компиляция приводит к следующей ошибке:

------ Build started: Project: ConsoleApplication1, Configuration: Debug x64 ------
1>In file included from C:\CODING\OTHERS\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cpp:1:
1>C:\CODING\OTHERS\ConsoleApplication1\ConsoleApplication1\AAD3.h(34,38): : error : invalid arithmetic between different enumeration types ('Number::(unnamed enum at ./AAD3.h:151:2)' and 'ExprLog::(unnamed enum at ./AAD3.h:94:2)')
1> 34 | enum { numNumbers = LHS::numNumbers + RHS::numNumbers };
1> | ~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~
[/code]
он хорошо компилирует с теми компиляторами Intel только тогда, когда Language Standard C ++ равен iso c ++ 20 стандарт (/std: c ++ 20) или ниже.
Я попытался наивенно отменить оба элемента последней строки, чтобы без успеха. Я не вижу, как исправить код, чтобы избавиться от этой ошибки, когда я использую компилятор Intel. (Только с компилятором Intel, а не с Microsoft.)>

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

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

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

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

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

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