7

-Wextra次の警告/エラーを通知するGCC(4.7.2) (-Werror有効にしました):

データ型の範囲が制限されているため、比較は常に真です [-Wtype-limits]

次のコードの場合 [オンラインで試す]:

template <
    typename T,
    std::size_t N,
    bool = static_cast<std::size_t>(std::numeric_limits<T>::max()) < N>
struct validator {
    static constexpr bool validate(T value) {
        return static_cast<std::size_t>(value) < N;
    }
};

template <typename T, std::size_t N>
struct validator<T, N, true> {
    static constexpr bool validate(T) {
        return true;
    }
};

int main() {
    // Works
    static_assert(validator<int, 4>::validate(3), "Invalid");
    // Error :-(
    static_assert(validator<bool, 2>::validate(true), "Invalid");
}

validate次の関数を使用した場合など、通常の式のコンテキストで警告が発生する理由を理解しています。

template <typename T, std::size_t N>
bool validate(T value) {
    return static_cast<std::size_t>(value) < N;
}

– 実際、それが私が最初に特殊化されたテンプレートを使用している理由です (そして、正しいテンプレートの特殊化が使用され、最初のコードのエラーは、特殊化されていないテンプレートの関数内ではなく、テンプレート引数によって発生することに注意してください) . この警告を回避する方法はありますか? そうでない場合、それはコンパイラのバグではありませんか?

4

3 に答える 3

11

これは GCC トランクで修正されました。PR 11856を参照してください。

したがって、4 月下旬頃まで待って、GCC 4.8 を使用してください :-)

于 2013-01-19T23:36:57.720 に答える
2

これが修正されるまで待てないので (ジョナサンの回答を参照)、GCC#pragma拡張機能を使用して警告を選択的に無効にしました。

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
static_assert(validator<bool, 2>::validate(true), "Invalid");
#pragma GCC diagnostic pop

実際のエラーはテンプレート パラメータで発生しますが、残念ながら、これらのプラグマは呼び出しコードを囲む必要があることに注意してください。

于 2013-01-20T01:19:58.243 に答える
1

回避策は次のとおりです。

template <
    typename T,
    std::size_t N,
    bool = static_cast<std::size_t>(std::numeric_limits<T>::max()) < N>
struct validator {
    static constexpr bool validate(T value) {
        return size_t_cast(value) < N;
    }
private:
    static constexpr std::size_t size_t_cast(T value) {
        return value;
    }
};

template <typename T, std::size_t N>
struct validator<T, N, true> {
    static constexpr bool validate(T) {
        return true;
    }
};

これにより、GCC4.7.2でエラーなしでサンプルをコンパイルできます。

于 2013-01-20T17:46:57.560 に答える