Rokiのチラ裏

学生による学習のログ

Usage of void() in a comma-separated list

,で連結されたリストにおけるvoid()がどのような意味を持つのか。

a(), void(), b();

これは単純にオーバーロードされたoperator ,の呼び出しを防ぎ、言語による sequencing guarantees を保証するためのものである。void型のパラメータを持ったオーバーロードを定義する事はできないのでそれを防ぐ事ができる。例えば、variadic pack の展開ではよく用いられる。

template <class...> struct FirstType;
template <class Head, class... Tail>
struct FirstType <Head,Tail...> : std::enable_if<true, Head>{};

template <class T, class Allocator = std::allocator<T>>
struct X : std::vector<T, Allocator>{
    using std::vector<T,Allocator>::vector;
    
    template <class ValueType, std::enable_if_t<std::is_same<std::decay_t<ValueType>, X>::value, std::nullptr_t> = nullptr>
    ValueType&& operator,(ValueType&& x)
    {
        std::cout << "hoge" << std::endl;
        return std::forward<ValueType>(x);
    }
};

template <class Head, class... Tail>
Head&& do_something(Head&& head, Tail&&...)
{
    return std::forward<Head>(head);
}

template <class... Ts>
void f(Ts&&... ts)
{
    [[maybe_unused]] X<std::decay_t<typename FirstType<Ts...>::type>> a{X<int>{}, (do_something(std::forward<Ts>(ts)), void(), X<int>{})...}; // no hoge
}

see also: https://stackoverflow.com/questions/46198648/usage-of-void-in-a-comma-separated-list