启用程序在类模板中的不同上下文中的不同行为

时间:2013-10-16 17:35:06

标签: c++ sfinae typetraits class-template

为什么行为如此不同? #if 1版本成功(这很奇怪)编译并生成 stdout 的预期输出,但#if 0的版本不会:

#include <iostream>
#include <type_traits>

#include <cstdlib>

template< typename T >
class X
{

    struct B {};

public :

    struct U : B {};

};

template< typename T >
struct Y
{

    using X_type = X< T >;

    template< typename D,
              typename = typename std::enable_if< std::is_base_of< typename X_type::B, D >::value >::type >
    void operator () (D const &) const
    {
        std::cout << "allowed only for derived from B" << std::endl;
    }

};

template< typename T >
struct Z
{

    using X_type = X< T >;

    template< typename D >
    auto
    operator () (D const &) const
    -> typename std::enable_if< std::is_base_of< typename X_type::B, D >::value >::type
    {
        std::cout << "allowed only for derived from B!" << std::endl;
    }

};

int main()
{
    using T = struct W; // not matters
    using X_type = X< T >;
    using U = typename X_type::U;
#if 0
    using V = Y< T >;
#else
    using V = Z< T >;
#endif
    V v;
    v(U());
    return EXIT_SUCCESS;
}

这会产生错误(基本上'B'是私有的符合我的预期(实际上)):

<stdin>: In function 'int main()':
<stdin>:60:10: error: no match for call to '(V {aka Z<main()::W>}) (U)'
<stdin>:34:8: note: candidate is:
<stdin>:41:5: note: template<class D> typename std::enable_if<std::is_base_of<typename X<T>::B, D>::value>::type Z<T>::operator()(const D&) const [with D = D; T = main()::W]
<stdin>:41:5: note:   template argument deduction/substitution failed:
<stdin>: In substitution of 'template<class D> typename std::enable_if<std::is_base_of<typename X<T>::B, D>::value>::type Z<T>::operator()(const D&) const [with D = D; T = main()::W] [with D = X<main()::W>::U]':
<stdin>:60:10:   required from here
<stdin>:10:12: error: 'struct X<main()::W>::B' is private
<stdin>:41:5: error: within this context

g++ -v输出包含以下行:

gcc version 4.8.1 (rev3, Built by MinGW-builds project) 

除了B之外,我希望除X以外的任何地方都无法访问{{1}}。

问题仅发生在类模板上,但不适用于纯类(这里我们有两个相同的问题,因为这两个变体不需要编译,但是它们都是编译的。)

0 个答案:

没有答案