GCC 4.9中的模板实例化出错,在GCC 4.8中正常工作

Fre*_*pin 11 c++ gcc templates c++11

下面的测试代码与GCC 4.8(和4.7)完全一致:

#include <type_traits>

template<typename T, T &object, typename... Args>
struct Functor
{
    template<float (T::*function)(Args...), Args... args>
    struct Inner
    {
        float operator()() const
        {
            return (object.*function)(args...);
        }
    };
};

class Object
{
public:

    float someFunction()
    {
        return {};
    }

    float someFunctionWithArgument(int)
    {
        return {};
    }
};

Object object;

Functor<Object, object>::template Inner<&Object::someFunction> functor1;
Functor<Object, object, int>::template Inner<&Object::someFunctionWithArgument, 1> functor2;

int main()
{

}
Run Code Online (Sandbox Code Playgroud)

然而,对于GCC 4.9,它在实例化时失败了,并且没有任何帮助functor1:

$ g++ -std=c++11 test.cpp 
test.cpp: In instantiation of ‘struct Functor<Object, (* & object)>’:
test.cpp:33:24:   required from here
test.cpp:7:9: error: wrong number of template arguments (2, should be 1)
  struct Inner
         ^
test.cpp:7:9: error: provided for ‘template<class T, T& object, class ... Args> template<float (T::* function)(Args ...), Args ...args> struct Functor<T, object, Args>::Inner’
test.cpp:7:9: error: wrong number of template arguments (2, should be 1)
test.cpp:7:9: error: provided for ‘template<class T, T& object, class ... Args> template<float (T::* function)(Args ...), Args ...args> struct Functor<T, object, Args>::Inner’
test.cpp:33:35: error: ‘Inner’ in ‘struct Functor<Object, (* & object)>’ does not name a template type
 Functor<Object, object>::template Inner<&Object::someFunction> functor1;
Run Code Online (Sandbox Code Playgroud)

如果我用functor1实例化注释该行,其他一切(functor2)工作正常.

任何想法如何解决?

编辑:

我在GCC报告了一个错误 - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64514我们会看到......

Col*_*mbo 3

我不确定 GCC 是否完全错误。然而,问题案例基本上可以简化为

template<typename... T>
struct Functor
{
    template <T...>
    struct Inner
    {};
};

template struct Functor<>::Inner<>;
Run Code Online (Sandbox Code Playgroud)

这显示了与 GCC 相同的行为。这段代码似乎格式良好 - 即使Inner没有任何模板参数:

N为零时,扩展的实例化会产生一个空列表。这样的实例化不会改变封闭结构的句法解释,即使在完全省略列表会导致格式错误或导致语法歧义的情况下也是如此。

但如果我们现在更改代码以使用别名模板,它就会突然起作用:

template <typename... T>
struct Functor
{
    template <T...>
    using Inner = void;
};

using type = Functor<>::Inner<>;
Run Code Online (Sandbox Code Playgroud)

演示。在尝试将此解决方案应用于您的问题时,我不仅遇到了最初的错误,而且还遇到了第二个错误:

template <typename... Args>
struct Functor
{
    template <Args... args>
    struct A;

    template <Args... args>
    using B = A<args...>;
};

using type = Functor<>::B<>;
Run Code Online (Sandbox Code Playgroud)

main.cpp:8:24:错误:扩展模式“args”不包含参数包

 using B = A<args...>
                    ^
Run Code Online (Sandbox Code Playgroud)

我认为 GCC 在“空”非类型模板参数方面存在根本问题。