我在以下代码中遇到问题时遇到问题...

#include <functional>

template<typename... ARGS>
class MyClass {
public :
    void function(ARGS... args)
    {
    }
};

int main(int argc, char * argv[])
{
    MyClass<int>        myClassInt;      // works fine
    MyClass<int, float> myClassIntFloat; // works fine
    MyClass<void>       myClassVoid;     // <---- won't compile

    return 0;
}

如果我在上实例化MyClass无效,则Clang非常正确地拒绝编译此代码,抱怨 MyClass ::function 不是合法定义。但是,我拥有的真实类需要能够在void上实例化此类内容。我一直盯着这个看了很长时间,对于我需要解决的SFINAE jiggery-pokery模板我一无所知。

最佳答案

请在使用时使用MyClass<>或此技巧:

template<typename... ARGS>
class MyClass {
public :
  void function(ARGS... args)
  {}
};
template<>
class MyClass<void>:public MyClass<> {
public :
  using MyClass<>::MyClass; // inherit ctors
};

您还需要在MyClass<void>中执行其他操作,以充当MyClass<>的相对透明的代理。

我们可以通过不直接使用MyClass来避免这些问题。
template<typename... ARGS>
class MyClass_t {
public :
  void function(ARGS... args)
  {}
};

template<class...Args>
struct MyClass_helper {
  using type=MyClass_t<Args...>;
};
template<>
struct MyClass_helper<void>:MyClass_helper<> {};
template<class...Args>
using MyClass=typename MyClass_helper<Args...>::type;

现在,MyClass<void>扩展为MyClass_t<>MyClass<int, float>扩展为MyClass_t<int,float>

我们不直接使用MyClass_t,而是通过MyClass<...>命名。这种技术的缺点是MyClass<???>如果用作函数参数是非推论上下文;因此在这种情况下,您必须改用MyClass_t<???>,而他们不会看到void

我的首选解决方案是直接使用MyClass<>而不是MyClass<void>

10-08 09:44
查看更多