1

我正在用 C++ 编写一个小型库,我只希望在模板以算术类型为模板的情况下实例化模板,并且我发现了以下问题:

如果我有以下定义Foo

template<typename T, typename Enable = void>
class Foo;

template<typename T>
class Foo<T, std::enable_if<std::is_arithmetic<T>::value>::type> {
    Foo() = default;
    Foo( const Foo& ) = default;
    ~Foo() = default;

    template<typename U>
    Foo( std::initializer_list<U> list )
    {
        static_assert(std::is_convertible<U, T>::value, "Must use an initializer list with type convertible to T");

        for( std::size_t s = 0; s < 10; ++s )
        {
            tArray[s] = static_cast<U>(list[s]);
        }
    }

private:
    T       tArray[10];
};

我尝试按如下方式对其进行初始化:

int main()
{
    Foo<int> test{ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} };

    return 0;
}

我收到以下错误:

Foo<T, std::enable_if<std::is_arithmetic<T>::value>::type>::Foo( std::initializer_list<U> )[with T=int, U=int] 无法访问

我是std::enable_if在 TMP 中使用的新手,但根据cppreference.com看来这应该可以工作。我在这里缺少什么,或者这是 VS2013 的错误?

4

2 回答 2

5

您的初始化程序被声明为私有。将其声明为公开。并且不要忘记typename在使用时添加std::enable_if<>::type.

编辑: 中没有下标重载std::initializer_list

template<typename T, typename Enable = void>
class Foo;

template<typename T>
class Foo<T, typename std::enable_if<std::is_arithmetic<T>::value>::type> {

public:
    Foo() = default;
    Foo( const Foo& ) = default;
    ~Foo() = default;

    template<typename U>
    Foo( std::initializer_list<U> list )
    {
        static_assert(std::is_convertible<U, T>::value, "Must use an initializer list with type convertible to T");

        for( std::size_t s = 0; s < 10; ++s )
        {
            // ERROR
            // tArray[s] = static_cast<U>(list[s]);
        }
    }

private:
    T       tArray[10];
};
于 2014-07-07T08:26:50.500 回答
3

这与enable_if. 您没有在课程开始时指定任何成员访问控制,并且默认情况下是class成员(相对于struct成员)private。只需放在public:您的班级成员声明之前。

于 2014-07-07T08:27:03.940 回答