MSVC 2013/2015 internal compiler error
От: SaZ  
Дата: 04.09.15 11:50
Оценка:
Багрепорт: https://connect.microsoft.com/VisualStudio/Feedback/Details/1756242

Захотелось странного, опущу контекст.
Нужно написать функцию, которая вызовет метод класса и вернёт результат этого метода. Пробую:
(Студия падает на таком)
#include <type_traits>
#include <iostream>

template <typename T, typename M, typename ...Args>
auto invoke( T *object, M method, Args&&... args ) -> decltype( *method )
{
    return ( static_cast<T*>( object )->*method )( std::forward<Args>( args )... );
}

struct Foo
{
    int triple( int val )
    {
        return val * 3;
    }
};

int main()
{
    Foo foo;
    std::cout << invoke( &foo, &Foo::triple, 5 );   // output: 15

    return 0;
}


Но тут вижу, что я что-то делаю не так.

Собственно, вопросы: 1) куда написать багрепорт, 2) как объявить функцию invoke
Отредактировано 06.09.2015 11:41 SaZ . Предыдущая версия . Еще …
Отредактировано 04.09.2015 13:25 SaZ . Предыдущая версия .
Re: MSVC 2013/2015 internal compiler error
От: SaZ  
Дата: 04.09.15 12:34
Оценка:
Здравствуйте, SaZ, Вы писали:

SaZ> как объявить функцию invoke...


Студия вот такое скушала:
    #include <iostream>
 
    template< typename T >
    class Invoker
    {
    public:
        Invoker() = default;
        virtual ~Invoker() = default;
 
    public:
        template <typename M, typename ...Args>
        static typename std::result_of< M( Args... ) >::type invoke( T* object, M method, Args&&... args )
        {
            return ( object->*method )( std::forward<Args>( args )... );
        }
    };
 
    struct Foo
    {
        int triple( int val )
        {
            return val * 3;
        }
    };
 
    int main()
    {
        Foo foo;
 
        auto result = Invoker<Foo>::invoke( &foo, &Foo::triple, 5 );
        std::cout << result;    // 15
 
        return 0;
    }
Re: MSVC 2013/2015 internal compiler error
От: PM  
Дата: 04.09.15 13:14
Оценка: 4 (2) +1
Здравствуйте, SaZ, Вы писали:

SaZ>Захотелось странного, опущу контекст.

SaZ>Нужно написать функцию, которая вызовет метод класса и вернёт результат этого метода. Пробую:

...
SaZ>Собственно, вопросы: 1) куда написать багрепорт, 2) как объявить функцию invoke

Похоже, вы изобретаете std::invoke которая планируется в С++17.

Implementability

Proposed invoke function template may be implemented in terms of existing C++11 standard library components:


  template<typename Functor, typename... Args>
  typename std::enable_if<
    std::is_member_pointer<typename std::decay<Functor>::type>::value,
    typename std::result_of<Functor&&(Args&&...)>::type
  >::type invoke(Functor&& f, Args&&... args)
  { 
    return std::mem_fn(f)(std::forward<Args>(args)...); 
  }
   
  template<typename Functor, typename... Args>
  typename std::enable_if<
    !std::is_member_pointer<typename std::decay<Functor>::type>::value,
    typename std::result_of<Functor&&(Args&&...)>::type
  >::type invoke(Functor&& f, Args&&... args)
  { 
    return std::forward<Functor>(f)(std::forward<Args>(args)...); 
  }

  template<typename Return, typename Functor, typename... Args>
  Return invoke(Functor&& f, Args&&... args)
  {
    return invoke(std::forward<Functor>(f), std::forward<Args>(args)...);
  }
Re: Ответ на часть 2
От: SaZ  
Дата: 04.09.15 13:26
Оценка:
Собственно решение (ideone.com/cQEMM4):

    #include <iostream>
    #include <string>

    template< typename T >
    class Invoker
    {
    public:
        Invoker() = default;
        virtual ~Invoker() = default;

    public:
        template <typename R, typename ... Args1, typename ... Args2>
        static R invoke( T* object, R( T::* method )( Args1... ), Args2&&... args );
    };

    template <typename T>
    template <typename R, typename ... Args1, typename ... Args2>
    R Invoker<T>::invoke(T* object, R( T::* method)(Args1...), Args2&&... args)
    {
        return ( object->*method )( std::forward<Args1>( args )... );
    }

    
    struct Foo
    {
        int bar( const std::string& txt )
        {
            return 42;
        }
    };
    
    int main()
    {
        Foo foo;
        
        auto result = Invoker<Foo>::invoke( &foo, &Foo::bar, std::string() );
        std::cout << result;    // 42
        
        return 0;
    }


З.Ы, как я понимаю, костыльное. Я пока плохо представляю, что такое rvalue references, но учусь.
Отредактировано 04.09.2015 13:32 SaZ . Предыдущая версия .
Re: Куда отправить багрепорт
От: SaZ  
Дата: 05.09.15 10:36
Оценка:
Коллеги, так а куда нужно отправлять багрепорт по поводу internal compiler error? Через connect.microsoft.com мне почему-то не даёт.
Re[2]: VS bug: new int(1,2,"wtf")
От: Constructor  
Дата: 05.09.15 14:14
Оценка: 2 (1)
Здравствуйте, SaZ, Вы писали:

SaZ>Коллеги, так а куда нужно отправлять багрепорт по поводу internal compiler error? Через connect.microsoft.com мне почему-то не даёт.


Через Visual Studio Feedback Center. Но чтобы отправить багрепорт, необходимо войти в учетную запись Microsoft.

SaZ>Нужно написать функцию, которая вызовет метод класса и вернёт результат этого метода. Пробую:

SaZ>(Студия падает на таком)
SaZ>
SaZ>//...

SaZ>template <typename T, typename M, typename ...Args>
SaZ>auto invoke( T *object, M method, Args&&... args ) -> decltype( *method )
SaZ>{
SaZ>    return ( static_cast<T*>( object )->*method )( std::forward<Args>( args )... );
SaZ>}

Можно так:
template <typename T, typename M, typename ...Args>
auto invoke( T *object, M method, Args&&... args ) -> decltype( ( object->*method )( std::forward<Args>( args )... ) )
{
    return ( object->*method )( std::forward<Args>( args )... );
}

Можно так:
template <typename T, typename M, typename ...Args>
auto invoke( T *object, M method, Args&&... args ) -> std::result_of_t< M( T, Args... ) >
{
    return ( object ->*method )( std::forward<Args>( args )... );
}

А в VS2015 можно даже так (C++14):
template <typename T, typename M, typename ...Args>
auto invoke( T *object, M method, Args&&... args )
{
    return ( object->*method )( std::forward<Args>( args )... );
}
Re[3]: VS bug: new int(1,2,"wtf")
От: SaZ  
Дата: 05.09.15 15:17
Оценка:
Здравствуйте, Constructor, Вы писали:

C>Через Visual Studio Feedback Center. Но чтобы отправить багрепорт, необходимо войти в учетную запись Microsoft.


Зашёл под своей учёткой, которая с msdn подпиской (по BizSpark)

You are not authorized to submit the feedback for this connection.


Спасибо, зарегистрировался в connect и связал его со своей учёткой.
Отредактировано 05.09.2015 15:22 SaZ . Предыдущая версия .
Re[4]: VS bug: new int(1,2,"wtf")
От: _NN_ www.nemerleweb.com
Дата: 05.09.15 17:16
Оценка: +1
Здравствуйте, SaZ, Вы писали:

Cсылку на баг стоит выложить, чтобы мы могли проголосовать.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: VS bug: new int(1,2,"wtf")
От: SaZ  
Дата: 06.09.15 11:41
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Cсылку на баг стоит выложить, чтобы мы могли проголосовать.


Да, я хотел, но почему-то забыл: https://connect.microsoft.com/VisualStudio/Feedback/Details/1756242
На всякий случай, продублирую в первый пост.
Re: MSVC 2013/2015 internal compiler error
От: swingus  
Дата: 08.09.15 07:04
Оценка:
Вот это, кстати, лишнее и неправильное. Хотя, конечно, internal compiler error быть не должно.

-> decltype( *method )


Здравствуйте, SaZ, Вы писали:

SaZ>Багрепорт: https://connect.microsoft.com/VisualStudio/Feedback/Details/1756242


SaZ>Захотелось странного, опущу контекст.

SaZ>Нужно написать функцию, которая вызовет метод класса и вернёт результат этого метода. Пробую:
SaZ>(Студия падает на таком)
Отредактировано 08.09.2015 7:06 swingus . Предыдущая версия .
Re[2]: MSVC 2013/2015 internal compiler error
От: SaZ  
Дата: 08.09.15 07:06
Оценка:
Здравствуйте, swingus, Вы писали:

S>Вот это, кстати, лишнее и неправильное

S>...

Да, спасибо, я уже знаю. Я пока только осваиваю всю прелесть последних стандартов. Если есть какие-либо хорошие статьи (помимо справки на cppreference) по rvalue references и выводу типов, буду благодарен.
Re[3]: MSVC 2013/2015 internal compiler error
От: swingus  
Дата: 08.09.15 07:24
Оценка:
Ну это называется perfect forwarding problem.

Здравствуйте, SaZ, Вы писали:

SaZ>Да, спасибо, я уже знаю. Я пока только осваиваю всю прелесть последних стандартов. Если есть какие-либо хорошие статьи (помимо справки на cppreference) по rvalue references и выводу типов, буду благодарен.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.