Я хотел бы создать карту времени компиляции, в которой я свяжу число с членом класса. Затем верните член класса из функции во время компиляции.
Это текущий код
class MyClass
{
public:
float MemberA;
std::uint32_t MemberB;
};
int ProcessMember(int iMemberID, MyClass* pClass)
{
if (iMemberID == 1){
ProcessMember(pClass->MemberA);
}
else if (iMemberID == 2){
ProcessMember(pClass->MemberB);
}
endif
}
Вот что я хотел бы сделать:
template <class T>
void Multiply(T& CurrentValue)
{
CurrentValue = CurrentValue * 2;
}
int ProcessMember(int iMemberID, MyClass* pClass)
{
if (iMemberID == 1){
Multiply(func(1));
}
else if (iMemberID == 2){
Multiply(func(2));
}
endif
}
Таким образом, функция примет аргумент времени компиляции и укажет на член MyClass, который мне нужен.
Это возможно?
Я попробовал это:
template <typename T>
T& GetValueFromValueName(int MemberID, MyClass* pClass)
{
switch (MemberID)
{
case 1:
return pClass>MemberA;
case 2:
return pClass->MemberB;
}
}
Но это компилируется только в том случае, если я заранее укажу T перед вызовом функции.
вы можете сделать что-то вроде if constexpr (MemberId == 1) { return pClass->MemberA; } и убедиться, что у вас есть возвращаемый тип auto& (если вы действительно не уверены, что все ваши члены имеют один и тот же тип).
@PepijnKramer Пожалуйста, не отвечайте в комментариях.





Тип возвращаемого значения функции не может быть определен во время выполнения, но он должен быть известен во время компиляции.
Вы можете сделать memberID аргументом шаблона, а затем либо использовать специализации:
template <int memberID>
auto& GetValueFromValueName(MyClass* pClass);
template <>
auto& GetValueFromValueName<1>(MyClass* pClass) { return pClass->MemberA; }
template <>
auto& GetValueFromValueName<2>(MyClass* pClass) { return pClass->MemberB; }
Или constexpr, если:
template <int memberID>
auto& GetValueFromValueName(MyClass* pClass) {
if constexpr (memberID == 1) return pClass->MemberA;
else return pClass->MemberB;
}
Вот что я хотел бы сделать: [...]
Я полагаю, что на самом деле вы хотите не описывать каждый случай отдельно, потому что в этом случае писать test(1) вместо pClass->MemberA бесполезно. С учетом вышеизложенного вы можете написать:
template <int memberID>
auto ProcessMember(MyClass* pClass)
{
return Multiply(GetValueFromValueName<memberID>(pClass));
}
Используя библиотеку boost::pfr, вы можете получить доступ к переменным-членам с помощью констант времени компиляции.
#include <iostream>
#include <string>
#include "boost/pfr.hpp"
class MyClass {
public:
float MemberA;
std::uint32_t MemberB;
};
template <class T>
void Multiply(T& CurrentValue) {
CurrentValue = CurrentValue * 2;
}
template<std::size_t i>
void ProcessMember(MyClass* pClass) {
Multiply(boost::pfr::get<i>(*pClass));
}
int main() {
MyClass c{ 3.14f, 12345 };
std::cout << boost::pfr::io(c) << std::endl;
ProcessMember<0>(&c);
ProcessMember<1>(&c);
std::cout << boost::pfr::io(c) << std::endl;
}
Результат:
{3.14, 12345}
{6.28, 24690}
Вы об этом знаете: stackoverflow.com/questions/495021/… ?