2011-05-17 51 views
2

请原谅对C++类型演绎的无知,但我希望能够在参数包的定义中携带,以便稍后我可以测试内部类型。这可能吗?例如:推导参数包w/out显式传递它作为模板参数吗?

template <typename... Args> struct Entity { 

    struct Inner { 
     typedef Args... entity_args_t; 
    }; 

    struct SomeOtherInner { 
     typedef Args... entity_args_t; 
    }; 
}; 

struct ThingA : Entity<int, string> { 
}; 

struct ThingB : Entity<string, string> { 
}; 

//Want to accept variations of Entity<...>::Inner, 
//not Entity<...>::SomeOtherInner 
template<typename I> 
struct is_Entity_Inner { 
    static const bool value 
     = is_same< 
      typename Entity<typename I::entity_args_t...>::Inner 
      , I 
     >::value 
    ; 
}; 

Oui?非?

回答

2

定义:

template<typename ...> struct types; 

然后:

template <typename... Args> struct Entity { 

    struct Inner { 
     typedef types<Args...> entity_args_t; 
    }; 

    struct SomeOtherInner { 
     typedef types<Args...> entity_args_t; 
    }; 
}; 

那么你可以传递entity_args_t到有types<T...>一个局部特殊化的模板。如果你的typedef的Entity,可以改为写Entity<T...>部分特殊化,这可能是更明智的你的情况

template <typename... Args> struct Entity { 

    struct Inner { 
     // Equivalent: typedef Entity entity_args_t; 
     typedef Entity<Args...> entity_args_t; 
    }; 

    struct SomeOtherInner { 
     typedef Entity<Args...> entity_args_t; 
    }; 
}; 

所以具有entity_args_t等于Entity<Args...>一个typedef,你可以这样写如下(未经测试,但应工作):

template<typename ProbablyInner, typename ProbablyEntity> 
struct is_inner_impl : std::false_type 
{ }; 

template<typename ProbablyInner, typename ...Args> 
struct is_inner_impl<ProbablyInner, Entity<Args...>> 
    : std::is_same< 
     typename Entity<Args...>::Inner 
     ProbablyInner> 
{ }; 

template<typename ProbablyInner, typename = std::true_type> 
struct is_inner : std::false_type 
{ }; 

template<typename ProbablyInner> 
struct is_inner<ProbablyInner, 
    std::integral_constant<bool, is_inner_impl< 
    ProbablyInner, 
    typename ProbablyInner::entity_args_t>::value>> 
    : std::true_type 
{ }; 
+0

因此,在'is_Entity_Inner'元函数,我反而有'is_same :: value'? – 2011-05-17 16:05:33

+0

@pheedbaq请参阅更新。 – 2011-05-17 16:11:16

+0

@pheedbaq临界点是你访问':: entity_args_t'的地方。如果你希望'is_inner'产生任意其他类型的'false',你必须在SFINAE上下文中访问这个类型,这样如果没有成员叫做':: entity_args_t',那就没有硬编译时错误。 – 2011-05-17 16:25:18