The following code doesn't work with clang 3.3. but it does word with g++ 4.8.1. Boost version is 1.55.
#include <boost/concept_check.hpp>
template <typename X>
class ConceptsBase {};
int main() {
auto l = [](){};
BOOST_CONCEPT_ASSERT((ConceptsBase<decltype(l)>));
return 0;
}
g++ -std=c++0x test.cpp -I /home/wygos/libs/boost_1_55_0/include/ # works fine!
clang++ -std=c++0x test.cpp -I /home/wygos/libs/boost_1_55_0/include/
gives:
test.cpp:9:5: error: non-type template argument refers to function 'failed' that does not have linkage
BOOST_CONCEPT_ASSERT((ConceptsBase<decltype(l)>));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wygos/libs/boost_1_55_0/include/boost/concept/assert.hpp:44:5: note: expanded from macro 'BOOST_CONCEPT_ASSERT'
BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wygos/libs/boost_1_55_0/include/boost/concept/detail/general.hpp:70:6: note: expanded from macro 'BOOST_CONCEPT_ASSERT_FN'
&::boost::concepts::requirement_<ModelFnPtr>::failed> \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wygos/libs/boost_1_55_0/include/boost/concept/detail/general.hpp:38:17: note: non-type template argument refers to function here
static void failed() { ((Model*)0)->~Model(); }
My lucky guess is that it might be connected to:
http://llvm.org/bugs/show_bug.cgi?id=17030
Related
I'm trying to compile an example of some concept from cppreference with Clang on Mac and it fails. How can I fix the issue and compile the example?
Code:
#include <concepts>
#include <iostream>
template<std::regular T>
struct Single {
T value;
friend bool operator==(const Single&, const Single&) = default;
};
int main()
{
Single<int> myInt1{4};
Single<int> myInt2;
myInt2 = myInt1;
if (myInt1 == myInt2)
std::cout << "Equal\n";
std::cout << myInt1.value << ' ' << myInt2.value << '\n';
}
Terminal output:
% g++ -std=c++20 -o a a.cpp
a.cpp:4:15: error: no type named 'regular' in namespace 'std'
template<std::regular T>
~~~~~^
a.cpp:6:5: error: unknown type name 'T'
T value;
^
a.cpp:12:12: error: template argument for non-type template parameter must be an expression
Single<int> myInt1{4};
^~~
a.cpp:4:23: note: template parameter is declared here
template<std::regular T>
^
a.cpp:13:12: error: template argument for non-type template parameter must be an expression
Single<int> myInt2;
^~~
a.cpp:4:23: note: template parameter is declared here
template<std::regular T>
^
4 errors generated.
Compiler version:
% g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: x86_64-apple-darwin20.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
What's interesting is that the example successfully compiles on GodBolt with lower CLang version (12.0.1)
Consider the following program:
struct S {
enum E {
e
};
template<E> void f() = delete;
};
template<> void S::f<S::E::e>() {}
int main() {
S s;
s.f<S::E::e>();
}
GCC 5.4.0 compiles the code, while clang 3.8.0 fails:
$ clang++ -std=c++14 main.cpp
main.cpp:10:20: error: redefinition of 'f'
template<> void S::f<S::E::e>() {
^
main.cpp:8:20: note: previous definition is here
template<> void S::f<S::E::e>();
^
main.cpp:14:11: error: no matching member function for call to 'f'
s.f<S::E::e>();
~~^~~~~~~~~~
main.cpp:5:22: note: candidate template ignored: substitution failure [with $0 = S::E::e]
template<E> void f() = delete;
^
2 errors generated.
Is clang correct and GCC wrong or is it the opposite? Note that if the delete specifier is removed, then clang compiles the code.
this seems defect report Explicit specialization of deleted function template , as you can see from here the issue seems fixed in clang since 3.9.0.
I am trying to use boost::future .then() functionality.
The snippet is taken from Boost 1.54.0 thread synchronisation documentation
#include <string>
#include <boost/thread/future.hpp>
int main() {
boost::future<int> f1 = boost::async([]() { return 123; });
boost::future<std::string> f2 = f1.then([](boost::future<int> f)->std::string {
int x = f.get();
return ("Done" + std::to_string(x));
});
}
Setup :
Ubuntu 13.04
g++ version g++ (Ubuntu 4.8.1-2ubuntu1~13.04) 4.8.1
Boost version 1.54.0
command line :
g++ then_test.cc -std=c++0x -DBOOST_THREAD_VERSION=4 -I /home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost -L /home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/stage/lib -static -lboost_thread-mt -lboost_date_time-mt -lboost_system-mt -lpthread
Error:
g++ then_test.cc -std=c++0x -DBOOST_THREAD_VERSION=4 -I /home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost -L /home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/stage/lib -static -lboost_thread-mt -lboost_date_time-mt -lboost_system-mt -lpthread
then_test.cc: In function ‘int main()’:
then_test.cc:10:44: error: no matching function for call to ‘boost::future<int>::then(main()::__lambda1)’
});
^
then_test.cc:10:44: note: candidates are:
In file included from then_test.cc:2:0:
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:1598:9: note: template<class F> boost::future<typename boost::result_of<F(boost::future<R>&)>::type> boost::future<R>::then(F&&) [with F = F; R = int]
then(BOOST_THREAD_FWD_REF(F) func);
^
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:1598:9: note: template argument deduction/substitution failed:
In file included from then_test.cc:2:0:
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp: In substitution of ‘template<class F> boost::future<typename boost::result_of<F(boost::future<R>&)>::type> boost::future<R>::then(F&&) [with F = F; R = int] [with F = main()::__lambda1]’:
then_test.cc:10:44: required from here
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:62:29: error: no type named ‘type’ in ‘struct boost::result_of<main()::__lambda1(boost::future<int>&)>’
#define BOOST_THREAD_FUTURE future
^
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:3840:3: note: in expansion of macro ‘BOOST_THREAD_FUTURE’
BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func)
^
In file included from then_test.cc:2:0:
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:1601:9: note: template<class F> boost::future<typename boost::result_of<F(boost::future<R>&)>::type> boost::future<R>::then(boost::launch, F&&) [with F = F; R = int]
then(launch policy, BOOST_THREAD_FWD_REF(F) func);
^
/home/prakash/maidsafe/MaidSafe/build/boost_1_54_0/src/boost/boost/thread/future.hpp:1601:9: note: template argument deduction/substitution failed:
then_test.cc:10:44: note: cannot convert ‘<lambda closure object>main()::__lambda1{}’ (type ‘main()::__lambda1’) to type ‘boost::launch’
});
Please let me know if I am missing something here.
Passing future by reference to .then() fixes the compilation issue on gcc 4.8 & clang.
For windows and gcc 4.7 we additionally need to define BOOST_RESULT_OF_USE_DECLTYPE. (as per Xeo's comment). For gcc 4.8 & clang it seems available already.
boost::future<std::string> f2 = f1.then([](boost::future<int>& f)->std::string {
^
Why can I not get the template function to accept the lambda expression?
After searching high and low -- I seriously though that this would work, but this C++ code;
template <typename F> int proc(const F& lam)
{
return lam();
}
void caller()
{
int i = 42;
int j = proc( [&i]()->int{ return i/7; } );
}
An I get the following errors;
$ g++ x.cc
x.cc: In function ‘void caller()’:
x.cc:11:44: warning: lambda expressions only available with -std=c++0x or -std=gnu++0x [enabled by default]
x.cc:11:46: error: no matching function for call to ‘proc(caller()::<lambda()>)’
x.cc:11:46: note: candidate is:
x.cc:3:27: note: template<class F> int proc(const F&)
I'm on linux using g++ 4.6.3 and 4.7.2
Does anybody know what I have to do to pass on a lambda expression as a parameter to a receiving template function? -- I don't want to use the std::function -- so my only alternative is to create an ugly functor pattern.
Update: Tried to declare the argument const F& lam, but without success.
Update2: added call to compiler...
Since the lambda isn't an lvalue, you need to pass it by const reference:
template <typename F> int proc(const F& lam)
Make sure to use -std=c++11 with g++ 4.7.2 or -std=c++0x with g++ 4.6.3.
In the following code, it would appear that g++ 4.7.2 gets confused by a using based type alias.
The code:
#include <map>
enum class Direction
{
UP=-1,
DOWN=1
};
template <Direction dir>
struct Comparator
{
bool operator()(int lhs, int rhs) const
{
return lhs<rhs; // Comparison should be based on dir
// but let's not even use dir for now
}
};
template <Direction dir>
using IntToIntMap=std::map<int, int, Comparator<dir>>;
template <Direction dir>
void TestFunc()
{
using TheMap=IntToIntMap<dir>; // TheMap should be a synonym for
// IntToIntMap<dir>
typename IntToIntMap<dir>::value_type value1; // This compiles
typename TheMap::value_type value2; // This does not (???)
}
int main()
{
TestFunc<Direction::UP>();
}
Compile the code with:
g++ -std=c++11 -Wall --pedantic -o test test.cpp
Unexpected compile time errors:
test.cpp: In instantiation of 'void TestFunc() [with Direction dir =
(Direction)-1]
test.cpp:34:29: required from here
test.cpp:29:33: error: no type named 'value_type' in 'using TheMap =
IntToIntMap<dir>'
What is wrong with the line in question? Is the code in violation of the the C++11 standard or is this a g++ 4.7.2 bug? Live code in g++-4.7
It's fixed in gcc-4.8, per the comments:
4.7: http://coliru.stacked-crooked.com/view?id=9d55db125baaac0b169e61bbcfcb2a26-f2a3752efd0426bdaa29babef505f76e
4.8: http://coliru.stacked-crooked.com/a/6cd0ad895d067e51