es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Convirtiendo entre instancias de una plantilla de clase utilizando una función miembro.

Tengo un par de tipos fuertes que son solo alias de una plantilla de clase que contiene código compartido útil.

template <typename t="">
struct DiscretePosition {
public:
    int x{0};
    int y{0};

    // ... funciones genéricas útiles

};

struct ChunkTag{};
struct TileTag{};

using ChunkPosition = DiscretePosition<chunktag>;
using TilePosition = DiscretePosition<tiletag>;

Me gustaría escribir un constructor o una función auxiliar para ayudarme a convertir uno de estos tipos al otro.

TilePosition tilePosition{1, 1};

ChunkPosition chunkPosition{tilePosition};
// o
ChunkPosition chunkPosition{tilePosition.asChunkPosition()};

Este constructor simplemente tomaría los valores x e y subyacentes y los escalaría para que coincidan con el otro tipo utilizando una constante.

¿Hay alguna manera de hacer esto o tendría que usar una función libre?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, puedes definir un constructor de conversión en ChunkPosition que tome un argumento de tipo TilePosition y realice la escala necesaria. Aquí tienes un ejemplo de implementación:

    template <typename t="">
    struct DiscretePosition {
    public:
        int x{0};
        int y{0};
    
        // ... funciones genéricas útiles
    };
    
    struct ChunkTag{};
    struct TileTag{};
    
    using ChunkPosition = DiscretePosition<chunktag>;
    using TilePosition = DiscretePosition<tiletag>;
    
    const int TileToChunkScale = 16;
    
    struct ChunkPositionConverter {
        static ChunkPosition fromTilePosition(const TilePosition& tilePos) {
            ChunkPosition chunkPos;
            chunkPos.x = tilePos.x / TileToChunkScale;
            chunkPos.y = tilePos.y / TileToChunkScale;
            return chunkPos;
        }
    };
    
    struct ChunkPosition : public DiscretePosition<chunktag> {
    public:
        ChunkPosition() {}
    
        ChunkPosition(const TilePosition& tilePos)
            : DiscretePosition<chunktag>{ChunkPositionConverter::fromTilePosition(tilePos)} {}
    };
    

    Aquí, definimos una estructura auxiliar llamada ChunkPositionConverter que contiene un método llamado fromTilePosition que realiza la conversión. El constructor de ChunkPosition simplemente llama a este método y pasa la instancia resultante de DiscretePosition<chunktag> a su constructor base.

    Con esta implementación, puedes crear un ChunkPosition a partir de un TilePosition de la siguiente manera:

    TilePosition tilePos{1, 1};
    ChunkPosition chunkPos{tilePos}; // ChunkPosition{0, 0} en este ejemplo
    

    Alternativamente, podrías definir una función de conversión como una función libre, así:

    template <typename t="">
    struct DiscretePosition {
    public:
        int x{0};
        int y{0};
    
        // ... funciones genéricas útiles
    };
    
    struct ChunkTag{};
    struct TileTag{};
    
    using ChunkPosition = DiscretePosition<chunktag>;
    using TilePosition = DiscretePosition<tiletag>;
    
    const int TileToChunkScale = 16;
    
    ChunkPosition tileToChunk(const TilePosition& tilePos) {
        ChunkPosition chunkPos;
        chunkPos.x = tilePos.x / TileToChunkScale;
        chunkPos.y = tilePos.y / TileToChunkScale;
        return chunkPos;
    }
    

    Con esta implementación, puedes crear un ChunkPosition a partir de un TilePosition de la siguiente manera:

    TilePosition tilePos{1, 1};
    ChunkPosition chunkPos = tileToChunk(tilePos); // ChunkPosition{0, 0} en este ejemplo
    

    Ambos enfoques son válidos y la elección entre ellos depende de las preferencias personales y las especificidades de tu caso de uso.

Comments are closed.