const / non-const関数のペアを自動的に生成するマクロを思いつきました。
class A
{
int x;
public:
MAYBE_CONST(
CV int &GetX() CV {return x;}
CV int &GetY() CV {return y;}
)
// Equivalent to:
// int &GetX() {return x;}
// int &GetY() {return y;}
// const int &GetX() const {return x;}
// const int &GetY() const {return y;}
};
実装については、回答の最後を参照してください。
の引数MAYBE_CONST
が重複しています。最初のコピーでCV
は、何も置き換えられません。2番目のコピーではに置き換えられconst
ます。
CV
マクロ引数に出現できる回数に制限はありません。
ただし、少し不便があります。CV
括弧内にある場合は、この括弧のペアの前にCV_IN
:
// Doesn't work
MAYBE_CONST( CV int &foo(CV int &); )
// Works, expands to
// int &foo( int &);
// const int &foo(const int &);
MAYBE_CONST( CV int &foo CV_IN(CV int &); )
実装:
#define MAYBE_CONST(...) IMPL_CV_maybe_const( (IMPL_CV_null,__VA_ARGS__)() )
#define CV )(IMPL_CV_identity,
#define CV_IN(...) )(IMPL_CV_p_open,)(IMPL_CV_null,__VA_ARGS__)(IMPL_CV_p_close,)(IMPL_CV_null,
#define IMPL_CV_null(...)
#define IMPL_CV_identity(...) __VA_ARGS__
#define IMPL_CV_p_open(...) (
#define IMPL_CV_p_close(...) )
#define IMPL_CV_maybe_const(seq) IMPL_CV_a seq IMPL_CV_const_a seq
#define IMPL_CV_body(cv, m, ...) m(cv) __VA_ARGS__
#define IMPL_CV_a(...) __VA_OPT__(IMPL_CV_body(,__VA_ARGS__) IMPL_CV_b)
#define IMPL_CV_b(...) __VA_OPT__(IMPL_CV_body(,__VA_ARGS__) IMPL_CV_a)
#define IMPL_CV_const_a(...) __VA_OPT__(IMPL_CV_body(const,__VA_ARGS__) IMPL_CV_const_b)
#define IMPL_CV_const_b(...) __VA_OPT__(IMPL_CV_body(const,__VA_ARGS__) IMPL_CV_const_a)
以下をサポートしないC ++ 20以前の実装CV_IN
:
#define MAYBE_CONST(...) IMPL_MC( ((__VA_ARGS__)) )
#define CV ))((
#define IMPL_MC(seq) \
IMPL_MC_end(IMPL_MC_a seq) \
IMPL_MC_end(IMPL_MC_const_0 seq)
#define IMPL_MC_identity(...) __VA_ARGS__
#define IMPL_MC_end(...) IMPL_MC_end_(__VA_ARGS__)
#define IMPL_MC_end_(...) __VA_ARGS__##_end
#define IMPL_MC_a(elem) IMPL_MC_identity elem IMPL_MC_b
#define IMPL_MC_b(elem) IMPL_MC_identity elem IMPL_MC_a
#define IMPL_MC_a_end
#define IMPL_MC_b_end
#define IMPL_MC_const_0(elem) IMPL_MC_identity elem IMPL_MC_const_a
#define IMPL_MC_const_a(elem) const IMPL_MC_identity elem IMPL_MC_const_b
#define IMPL_MC_const_b(elem) const IMPL_MC_identity elem IMPL_MC_const_a
#define IMPL_MC_const_a_end
#define IMPL_MC_const_b_end