【问题标题】:Compilation error C2976 with boost::asio by using template with std::enable_if使用带有 std::enable_if 的模板,带有 boost::asio 的编译错误 C2976
【发布时间】:2018-02-14 14:03:14
【问题描述】:

我编写了一个 c++ 类,通过在测试程序中使用它可以正常工作。通过在我的项目中使用它,出现编译错误 C2976。所以我减少了代码来显示问题:

source.h

#include <type_traits>
//#include <boost/asio.hpp>

namespace myNS {

class Dummy {
public:
   Dummy() {}
   ~Dummy() {}

   template<class T> struct _isValidType : std::false_type {};
   template<> struct _isValidType<bool> : std::true_type {};
   template<> struct _isValidType<int> : std::true_type {};
   template<class T> struct isValidType : _isValidType<std::remove_cv_t<T>>::type {};

   template<typename OUT, typename std::enable_if<isValidType<OUT>::value>::type* dummy = nullptr>
   OUT doSomething() {  OUT out{}; return out; }
};

} /* namespace myNS */

source.cpp

#include "source.h"

int main() {
   myNS::Dummy d;
   bool b = d.doSomething<bool>();
}

不包含 boost::asio 时没有编译错误。通过包含 boost::asio 编译器在最后一个模板定义上运行错误:

source.h(14): error C2976: "Dummy::isValidType": Nicht genügend Vorlage-Argumente.
source.h(12): note: Siehe Deklaration von "Dummy::isValidType"
source.h(14): error C2955: "Dummy::isValidType" : Für die Verwendung von Klasse Vorlage ist eine Vorlage-Argumentliste erforderlich
source.h(12): note: Siehe Deklaration von "Dummy::isValidType"
source.h(15): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.

有人知道这个问题吗?是 MSVC 的 boost::asio 的错,还是我的错?在这个例子中 boost::asio 不是必须包含的,但在我的项目中我必须包含它。
我正在使用 MS Visual Studio Community 2017 V 15.5.5 并使用 boost 库 v1.66.0。

谢谢!

【问题讨论】:

标签: c++ templates boost enable-if asio


【解决方案1】:

这是由一些不好的#define OUT ... 引起的(参见Live Repro)。

将您的 OUT 类型参数重命名为其他名称,并将显式特化移到类之外。

class Dummy {
public:
    // ...
    template<typename T, typename std::enable_if<isValidType<T>::value>::type* dummy = nullptr>
    T doSomething() {  T out{}; return out; }
}:

template<> struct Dummy::_isValidType<bool> : std::true_type {};
template<> struct Dummy::_isValidType<int> : std::true_type {};

【讨论】:

  • 感谢您的回答,但仍然是同样的问题。不管是在类之外还是在命名空间之外。
  • @werner 将 OUT 重命名为 T 之类的
  • 谢谢!问题是OUT。如果我更改为 T 或其他字符,它可以正常工作。 OUT 和 IN 不起作用。什么原因?
  • @werner 我想它来自一些 Windows.h 标头
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
相关资源
最近更新 更多