Namaran

Code daily. Without assist.

2026-09-16

meters.cpp

#include <iostream>

class Meters {
public:
    Meters(double value) : value(value) {}
    double value;
};

void print_distance(Meters m) {
    std::cout << m.value << " m\n";
}

int main() {
    double centimeters = 250.0;
    print_distance(centimeters);
}

centimetersはセンチメートル単位の値なので、本来はメートルに換算してから渡すべきですが、print_distance(centimeters)は換算なしでもコンパイルでき、"250 m"と出力されてしまいます。何が問題で、どう直せばよいでしょうか?

Answer

Meters(double value)explicitが付いていないため、doubleを渡すとどこでも暗黙にMetersへ変換されてしまいます。単位を換算し忘れてdoubleのcentimetersをそのまま渡しても、型検査はそれを止めてくれません。コンストラクタにexplicitを付ければ、この暗黙変換自体がコンパイルエラーになって単位の換算漏れに気付けます。呼び出し側では、意図どおりセンチメートルをメートルへ換算してから明示的にMetersを作ります:

class Meters {
public:
    explicit Meters(double value) : value(value) {}
    double value;
};

int main() {
    double centimeters = 250.0;
    print_distance(Meters(centimeters / 100.0));
}