次のコードが有効かどうかお尋ねしたいです。
1 つの式でパラメーター パックを複数回展開する可能性について疑問に思います。
#include <iostream>
#include <tuple>
class ExpandWithConstructor
{
public:
template <typename ... T>
ExpandWithConstructor( T... args) { }
};
template <typename T>
int PrintArgs( T arg )
{
std::cout << arg << ", ";
return 0;
}
template <typename Head, typename ... T>
class DebugPrinter: public DebugPrinter<T...>
{
public:
DebugPrinter() { }
template< typename ...Y>
DebugPrinter( Y ... rest )
{
std::cout << "Construction of: " << __PRETTY_FUNCTION__ << " Values: " ;
ExpandWithConstructor{PrintArgs( rest)...};
std::cout << std::endl;
}
};
template <typename Head>
class DebugPrinter< Head >
{
public:
};
template <typename ... T>
class TypeContainer: public std::tuple<T...>
{
public:
TypeContainer(T... args):std::tuple<T...>(args...){};
};
template <typename... T1> class CheckVariadic;
template <typename... T1, typename ...T2>
class CheckVariadic< TypeContainer<T1...>, TypeContainer<T2...>> :
public DebugPrinter< T1, T2, T1...>...
{
public:
CheckVariadic( T1... args1, T2... args2, T1... args3): DebugPrinter< T1, T2, T1...>(args1, args2..., args1)... {}
};
int main()
{
CheckVariadic< TypeContainer<int,float>, TypeContainer<char, void*>> checkVariadic1{ 1,2.2,'c',(void*)0xddddd,5,6.6,};
}
ご覧のとおり、コードは次を使用しています: DebugPrinter< T1, T2, T1...>...
T1 が "int,float" で指定され、T2 が "char,void*" である場合、これは次のように展開されます。
DebugPrinter< T1, T2, int, float>...
に展開します
DebugPrinter< int, char, int, float>
DebugPrinter< float, void*, int, float>
同じ展開は次の場合にも当てはまります。
DebugPrinter< T1, T2, T1...>(args1, args2..., args1)...
コードはclang3.3でコンパイルされますが、gcc4.8.1ではコンパイルされないため、コードが有効かどうかを尋ねたい.
更新: gcc 7.2 はまだコードをコンパイルしませんでした。