@@ -160,7 +160,7 @@ class GenericRootTreeReader
160160 : mInput (treename)
161161 {
162162 mInput .SetCacheSize (0 );
163- parseConstructorArgs (std::forward<Args>(args)...);
163+ parseConstructorArgs< 0 > (std::forward<Args>(args)...);
164164 }
165165
166166 // / add a file as source for the tree
@@ -279,6 +279,11 @@ class GenericRootTreeReader
279279 TClass* classinfo = nullptr ;
280280 };
281281
282+ // helper for the invalid code path of if constexpr statement
283+ template <typename T>
284+ struct type_dependent : std::false_type {
285+ };
286+
282287 // / add a new branch definition
283288 // / we allow for multiple branch definition for the same key
284289 void addBranchSpec (KeyType key, const char * branchName)
@@ -309,30 +314,45 @@ class GenericRootTreeReader
309314 }
310315 }
311316
317+ // special helper to get the char argument from the argument pack
318+ template <typename T, typename ... Args>
319+ const char * getCharArg (T arg, Args&&...)
320+ {
321+ static_assert (std::is_same<T, const char *>::value, " missing branch name after publishing key, use const char* argument right after the key" );
322+ return arg;
323+ }
324+
312325 // / helper function to recursively parse constructor arguments
313- template <typename U , typename V , typename ... Args>
314- void parseConstructorArgs (U key, V&& arg, Args&&... args)
326+ template <size_t skip , typename U , typename ... Args>
327+ void parseConstructorArgs (U key, Args&&... args)
315328 {
329+ if constexpr (skip > 0 ) {
330+ return parseConstructorArgs<skip - 1 >(std::forward<Args>(args)...);
331+ }
316332 if constexpr (std::is_same<U, const char *>::value) {
317333 addFile (key);
318- parseConstructorArgs (std::move (arg), std::forward<Args>(args)...);
319334 } else if constexpr (std::is_same<U, int >::value) {
320335 mMaxEntries = key;
321- parseConstructorArgs (std::move (arg), std::forward<Args>(args)...);
322336 } else if constexpr (std::is_same<U, PublishingMode>::value) {
323337 mPublishingMode = key;
324- parseConstructorArgs ( std::move (arg), std::forward<Args>(args) ...);
325- } else {
338+ } else if constexpr ( sizeof ...(Args) > 0 ) {
339+ const char * arg = getCharArg (std::forward<Args>(args)...);
326340 if (arg != nullptr && *arg != 0 ) {
327341 // add branch spec if the name is not empty
328342 addBranchSpec (KeyType{ key }, arg);
329343 }
330- parseConstructorArgs (std::forward<Args>(args)...);
344+ return parseConstructorArgs<1 >(std::forward<Args>(args)...);
345+ } else {
346+ static_assert (type_dependent<U>::value, " argument mismatch, allowed are: file names, int to specify number of events, publishing mode, and key-branchname pairs" );
331347 }
348+ parseConstructorArgs<0 >(std::forward<Args>(args)...);
332349 }
333350
334351 // this terminates the argument parsing
335- void parseConstructorArgs () {}
352+ template <size_t skip>
353+ void parseConstructorArgs ()
354+ {
355+ }
336356
337357 // / the input tree, using TChain to support multiple input files
338358 TChain mInput ;
0 commit comments