Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 专门化模板函数以生成编译时错误_C++_Templates_Boost_Static Assert - Fatal编程技术网

C++ 专门化模板函数以生成编译时错误

C++ 专门化模板函数以生成编译时错误,c++,templates,boost,static-assert,C++,Templates,Boost,Static Assert,如果用户试图使用给定的模板参数调用模板函数,如何专门化模板函数以在编译时生成错误 我能够通过使用以下习惯用法获得模板类的这种行为 template <typename T> class MyClass< std::vector<T> >; 但是,这会生成以下编译时错误,即使我没有尝试使用我试图禁止的模板参数调用函数的实例 error: invalid application of 'sizeof' to incomplete type 'boost::STA

如果用户试图使用给定的模板参数调用模板函数,如何专门化模板函数以在编译时生成错误

我能够通过使用以下习惯用法获得模板类的这种行为

template <typename T>
class MyClass< std::vector<T> >;
但是,这会生成以下编译时错误,即使我没有尝试使用我试图禁止的模板参数调用函数的实例

error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>'
我发现了,但它并没有提供任何我认为适用于我的见解。有人能帮忙吗?

用于生成编译时布尔值,然后可与BOOST\u STATIC\u ASSERT一起使用以执行检查

template <typename T>
T bar(const int) 
{
  BOOST_STATIC_ASSERT_MSG((!boost::is_same<T, std::string>::value), 
                          "T cannot be std::string");
  return T();
}

bar<int>(10);
bar<std::string>(10);  // fails static assertion
用于生成编译时布尔值,然后可与BOOST\u STATIC\u ASSERT一起使用以执行检查

template <typename T>
T bar(const int) 
{
  BOOST_STATIC_ASSERT_MSG((!boost::is_same<T, std::string>::value), 
                          "T cannot be std::string");
  return T();
}

bar<int>(10);
bar<std::string>(10);  // fails static assertion
<>似乎C++不允许专门化模板成员函数。所以,如果您想使用相同的接口,您应该使用其他技术。我想使用trait_type来实现这一点

template <class T>
struct is_string : false_type {};
template <>
struct is_string<string> : true_type {};

template <typename T>
class MyClass {
 private:
  T bar(const int arg, false_type) const {
    return T();
  }

  std::string bar(const int arg, true_type) const {
    return "123";
  }
 public:
  T bar(const int arg) const {
    return bar(arg, is_string<T>());
  }
};
如果不能使用C++11,则必须自己实现false_类型和true_类型。或者您可以使用specialize模板类

> C++似乎不允许专门化模板成员函数。所以,如果您想使用相同的接口,您应该使用其他技术。我想使用trait_type来实现这一点

template <class T>
struct is_string : false_type {};
template <>
struct is_string<string> : true_type {};

template <typename T>
class MyClass {
 private:
  T bar(const int arg, false_type) const {
    return T();
  }

  std::string bar(const int arg, true_type) const {
    return "123";
  }
 public:
  T bar(const int arg) const {
    return bar(arg, is_string<T>());
  }
};


如果不能使用C++11,则必须自己实现false_类型和true_类型。或者您可以使用specialize模板类

嗯,也许你可以使用这个函数模板的显式专门化就像一个简单的函数,所以任何静态断言都会被触发。@Sumsar1812,你指的是哪个链接?这是你建议的吗。。。BOOST_STATIC_ASSERTtypeidstd::string!=IDT型;这会引发编译器错误。。。错误:“typeid”运算符不能出现在常量表达式中什么是foo?一个名称空间,一个类?嗯,也许你可以使用它。一个函数模板的显式专门化就像一个简单的函数,所以任何静态断言都会被触发。@Sumsar1812,你指的是哪个链接?这是你建议的吗。。。BOOST_STATIC_ASSERTtypeidstd::string!=IDT型;这会引发编译器错误。。。错误:“typeid”运算符不能出现在常量表达式中什么是foo?一个名称空间,一个类?这会引发一个不必要的编译时错误。。。增强\静态\断言!boost::is_same::value,我的消息;产生错误:宏BOOST\u STATIC\u ASSERT传递了3个参数,但只接受1个参数,并且错误:“BOOST\u STATIC\u ASSERT”未在此范围内声明。请注意,我调用BOOST\u STATIC\u ASSERTtrue时没有问题。@DanForbes注意到我的示例中额外的一组括号吗?:如果没有这些,则预处理器会将is_中的逗号解释为参数分隔符。另外,如果要添加message.Derp,则需要BOOST\u STATIC\u ASSERT\u MSG。接受这个答案,因为它很简单,并且提供了我想要的确切行为。这会抛出一个不需要的编译时错误。。。增强\静态\断言!boost::is_same::value,我的消息;产生错误:宏BOOST\u STATIC\u ASSERT传递了3个参数,但只接受1个参数,并且错误:“BOOST\u STATIC\u ASSERT”未在此范围内声明。请注意,我调用BOOST\u STATIC\u ASSERTtrue时没有问题。@DanForbes注意到我的示例中额外的一组括号吗?:如果没有这些,则预处理器会将is_中的逗号解释为参数分隔符。另外,如果要添加message.Derp,则需要BOOST\u STATIC\u ASSERT\u MSG。接受这个答案,因为它很简单,并且提供了我想要的确切行为。虽然我很欣赏你的答案,而且它可能会起作用,但上面@Praetorian提供的答案更简单,并且提供了我想要的确切行为。我很确定std::true_类型和std::false_类型都在C++03中,不是吗?或者至少在Tr1中?@仅在Tr1.C++中的MooEngDek允许完全专门化模板成员函数。但问题不在于它。即使将std::string作为模板参数传递,您的代码也能成功编译。虽然我很欣赏您的答案,而且它可能会起作用,但上面@Praetorian提供的答案更简单,并提供了我所寻找的确切行为。我非常确定std::true_type和std::false_type都在C++03中,不是吗?或者至少在Tr1中?@仅在Tr1.C++中的MooEngDek允许完全专门化模板成员函数。但问题不在于它。即使将std::string作为模板参数传递,代码也能成功编译。
template <class T>
struct is_string : false_type {};
template <>
struct is_string<string> : true_type {};

template <typename T>
class MyClass {
 private:
  T bar(const int arg, false_type) const {
    return T();
  }

  std::string bar(const int arg, true_type) const {
    return "123";
  }
 public:
  T bar(const int arg) const {
    return bar(arg, is_string<T>());
  }
};